单元测试

单元测试 单元测试的目的并不是查找bug,而是帮助我们更好的设计我们的代码,如何合理的来拆分我们的代码。 单元测试vs集成测试 集成测试检查各个组件间协作运行是否正常,单元测试检查应用程序中的一个某一个小的功能模块。 相关工具 以python为例 unittest nose or nose2 pytest 其中,nose和nose2基于unittest, 如果使用python2可以使用前两中,pytest要求python3.7+。pytest有较多插件, 显示内容更为丰富一些。 用官方例子比较一下: 1 2 3 4 5 6 # content of test_sample.py def inc(x): return x + 1 def test_answer(): assert inc(3) == 5 直接运行pytest 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 [garlic@centos8 pytest]$ pytest ========================================= test session starts ========================================= platform linux -- Python 3.6.8, pytest-7.0.1, pluggy-1.0.0 rootdir: /home/garlic/pytest/pytest collected 1 item test_sample.py F [100%] ============================================== FAILURES =============================================== _____________________________________________ test_answer _____________________________________________ def test_answer(): > assert inc(3) == 5 E assert 4 == 5 E + where 4 = inc(3) test_sample.py:7: AssertionError ======================================= short test summary info ======================================= FAILED test_sample.py::test_answer - assert 4 == 5 ========================================== 1 failed in 0.03s ========================================== [garlic@centos8 pytest]$ cat test_sample.py # content of test_sample.py def inc(x): return x + 1 def test_answer(): assert inc(3) == 5 如果用unittest要写成下面的样子: ...

2022-05-08 · 3 min · 492 words · Garlic Space

Non-Constructible Change

问题: 给定一系列正整数,代表硬币的面值,找到无法从这些整数组连续组合成的最小值。比如 coins=[1,2,5], 最小不能组合成的值为4. 解答: 如果下一个整数大于前面所有值的累积和 + 1,那么就知道最小值,如果能被组合范围[0, sum], 下一个数据为y, 如果能构造出联系数据 sum+1 要在 [y,sum+y]范围内。也就是y<=sum+1<=sum+y。 由于排序数组 y>=1, 也就是满足y>sum+1。就可以找到最小组合值。 1 2 3 4 5 6 7 8 9 10 11 def nonConstructibleChange(coins): # Write your code here. coins.sort() currentChangeCreated = 0 for coin in coins: if coin > currentChangeCreated + 1: return currentChangeCreated + 1 currentChangeCreated += coin return currentChangeCreated + 1 ...

2022-05-04 · 1 min · 69 words · Garlic Space

Debugging NGINX

这篇文章来自nginx document https://docs.nginx.com/nginx/admin-guide/monitoring/debugging/ nginx的故障排除和大多数程序一样, 可以通过gdb调试二进制文件, 增加debug日志,或者分析coredump文件方式解决。 配置nginx nginx 商业版本从Release8开始已经提供nginx-debug版本,使用这个版本直接在配置文件中将日志设置成debug级别即可。 1 error_log /var/log/nginx/error.log debug; 如果是开源版本, 需要增加**--with-debug**标识重新编译, 步骤如下 1 2 3 4 $nginx -V 2>&1 | grep arguments $./congfigure --with-debug <other configure arguments> $sudo make $sudo make install 调试符号 和大多数调试都需要增加调试符号,他可以提供除了内存地址以外的其他信息, 将可执行文件中的内存地址和如变量名称, 函数,类,数据结构,源码行数这些代码中的信息关联起来。 编译通过增加**-g**可以包含调试符号。 1 $ ./configure --with-debug --with-cc-opt='-O0 -g' Debug日志 当二进制支持debug日志后,还需要在配置文件中配置日志路径。日志可以存放到内存中, 标准输出中,或者指定的文件中。默认配置可以看到通过error_log变量指定到文件中。 1 2 $ cat /etc/nginx/nginx.conf $ error_log /var/log/nginx/error.log debug; 内存方式 配置 1 error_log memory:32m debug; 调试 1 $sudo gdb -p <pid> 将调试脚本拷贝到gdb中,按回车日志就会输出到 debug_log.txt文件中 ...

2022-05-01 · 2 min · 329 words · Garlic Space

mysql error 1364 Field doesn't have a default values

问题描述 前一阵在做一个系统迁移工作, mysql数据库版本进行了升级, 数据库mariadb版本原有版本 5.5.56,升级后版本10.3.9. 1 2 3 4 5 6 $ mysql -V or $ mysql > select version(); 升级后原有功能报1364错误, 原因由于数据库中的SQL mode 默认定义调整。 可以通过以下命令进行看出 1 $mysql -u -e "select @@sql_mode" mysql 5.7版本以后默认打开了打开了STRICT_TRANS_TABLES。 可以通过配置文件修改,设置为"“则为取消 1 2 [mysqld] sql-mode = "STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" 或者使用sql, 多个模式间的用逗号分割不能有空格。 1 >SET session sql_mode = 'modes...'; 立即生效设置当前session sql_mode sql_mode mysql 文档关于STRICT_TRANS_TABLES描述。 1 2 Strict SQL Mode Strict mode controls how MySQL handles invalid or missing values in data-change statements such as INSERT or UPDATE. A value can be invalid for several reasons. For example, it might have the wrong data type for the column, or it might be out of range. A value is missing when a new row to be inserted does not contain a value for a non-NULL column that has no explicit DEFAULT clause in its definition. (For a NULL column, NULL is inserted if the value is missing.) Strict mode also affects DDL statements such as CREATE TABLE. 严格模式控制MySQL如何处理数据如插入或更新中的无效值。例如,它可能具有错误的列数据类型,或者可能超出范围。当要插入的新行不包含一个非NULL列的值时,其定义中没有明确的默认子句。(对于null列,如果丢失了值,则将插入空。)严格模式还会影响诸如创建表之类的DDL语句. ...

2022-04-30 · 2 min · 411 words · Garlic Space

git 常用命令

查看分支 1 git branch -av 导出分支 1 2 git remote add origin ssh://git@ip:port/branch.git git checkout -b localbranch origin/remotebranch 稀疏导出 1 2 3 4 5 6 git init <project> cd <project> git config core.sparsecheckout true echo "path1/" >> .git/info/sparse-checkout echo "path2/" >> .git/info/sparse-checkout git pull origin remotebranch 恢复误删除文件 1 2 3 git status git reset HEAD git checkout . non-fast-forward 1 2 git fetch origin master git merge origin FETCH_HEAD 本地rebase导致non-fast-forward 1 2 git reflog 查看HEAD的移动历史 git reset --hard xxxx 提交 1 git push origin localbranchname ...

2022-04-05 · 1 min · 89 words · Garlic Space

Message-Based Load Balancing

最近工作中涉及到一些负载均衡一些知识这里今天这篇文章是F5的 Message-Based Load Balancing。 这是2009年发布的一篇文章,后续F5已经建议从MBLB迁移到MRP功能模块。 原文链接: https://www.f5.com/services/resources/white-papers/message-based-load-balancing Migrating MBLB Functionality to MRPF Functionality https://techdocs.f5.com/kb/en-us/products/big-ip_ltm/manuals/product/bigip-mblb-to-mrf-migration-12-0-0/2.html 在高可用可扩展性应用场景中,经常能看到负载均衡身影,有硬件设备也有软件实现,由于Web应用广泛应用负载平衡也变得更加适用于HTTP这些协议。 与HTTP不同也会有一些异步的协议:Diameter,RADIUS and SIP,由于大多数负载的设计针对同步消息传输环境,这使得原有的负载难以分发这些协议。 文中主要提到SIP协议的复杂性,SIP是一种基于文本的协议,它的语法和消息非常类似于HTTP协议,不同之处在于SIP不仅可以用TCP,也可以用UDP封装, 对移动业务支持比较好。 如果举一个更好理解的例子, 由于在金融机构工作,一些系统使用长连接异步的通讯方式,比如银联CUPS系统卡接口, 使用的是异步长链接模式,如何做到在前端接入和后端系统均为长连接情况下做到,报文级别的负载? 挑战 Asynchronous Messaging 异步消息 下面是同步场景,客户端发送一个请求同步等待一个响应。 下面是异步场景,客户端发送n个请求,服务端返回n个响应。 这种场景下没有明显的客户端服务端之分,可以看到右边的服务也可能主动发起请求到左边的服务。 Long-Lived Sessions 长连接 在传统负载中,每次会话或连接基础上完成。在同一会话中收到的所有请求都是相同服务器的负载平衡。当通信完成时,会话终止。 长连接场景中导致流量无法均匀分配到指定服务上。 Message-Oriented Communication 消息处理 传统负载均衡维护请求和服务器端连接之间的1:1关系, 针对这种异步长连接场景,就需要做到1:n。也就是需要将请求均匀发送到后端的服务上。这时候就需要区分服务边界,需要多报文进行标识处理。 这里文档中提到AVP, 对AVP的理解,就是报文的标识,也就是需要从报文中找到唯一能标识他的信息。 解决方案 也就是MBLB (Message-Based Load Balancing)。 MBLB使Big-IP LTM能够以交钥匙方式实现特定协议支持,同时仍通过iRules实现客户和环境特定的自定义。 可以看到他提取A报文中的AVP代码根据负载策略送到上面服务器, 提起B报文的AVP送到下面服务器。 总结 F5 TMOS架构提供了F5能够快速实现基于消息的协议, 保持通过iRules翻遍实现了各位异步并进行双向通信的协议适配。 参考及引用 文中图片来自原文 封面图片from 陳丁光

2022-04-01 · 1 min · 59 words · Garlic Space

Tournament winner

问题 循环赛每个队对战所有其他对手, 胜利者记3分, 失败者记1分. 两个数组做为输入, competitions,存放主场队和客场队, results存放结果, 1表示主队获胜, 0表示客队获胜。返回分数最高的队伍。 解答 使用一个hash表,key为队伍名称, 值为累计分数。时间复杂度O(n) 循环赛的数量, 空间复杂度O(k), 参赛队数量。对应hash表需要的容量。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 def tournamentWinner(competitions, results): currentBestTeam = "" scores = {currentBestTeam: 0} for idx, competition in enumerate(competitions): result = results[idx] homeTeam, awayTeam = competition winningTeam = homeTeam if result == 1 else awayTeam updateScores(winningTeam, 3 , scores) if scores[winningTeam] > scores[currentBestTeam]: currentBestTeam = winningTeam return currentBestTeam def updateScores(team, points, scores): if team not in scores: scores[team] = 0 scores[team] += points 参考及引用 图片from Akihito Ichiyama

2022-03-30 · 1 min · 99 words · Garlic Space

vim putty gruvbox

putty 使用的是putty进行访问,可以使用gruvbox 提供的配色访问进行调整。 可以使用下面链接进去: 1 https://github.com/morhetz/gruvbox-contrib/tree/master/putty 其他工具 如果使用是其他工具也可以找到对应的工具 1 https://github.com/morhetz/gruvbox-contrib 操作系统自带Vim 如果使用的操作系统自带Vim工具,可以下载下面工具编辑~/.vimrc 1 2 $ curl -fLo ~/.vim/autoload/plug.vim --create-dirs \ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim 1 2 3 4 5 6 7 $ cat ~/.vimrc 。。。 call plug#begin() Plug 'morhetz/gruvbox' call plug#end() 。。。 $ vi打开后 1 :PlugInstall grubbox提供的一些安装方法 1 https://github.com/morhetz/gruvbox/wiki/Installation 参考及引用 https://opensource.com/article/20/2/how-install-vim-plugins 图片from 江金倫 彰化縣-竹塘鄉-竹塘木棉道

2022-03-21 · 1 min · 51 words · Garlic Space

centos8 yum 相关国内镜像仓库弃用(deprecated)

今天centos8使用yum安装软件时报错。 1 2 - Curl error (28): Timeout was reached for http://mirrors.aliyuncs.com/centos/8/BaseOS/x86_64/os/repodata/repomd.xml [Connection timed out after 30001 milliseconds] - Status code: 404 for https://mirrors.aliyun.com/centos/8/BaseOS/x86_64/os/repodata/repomd.xml (IP: 42.81.213.224) 查看一下:https://mirrors.aliyun.com/centos/8/readme 1 This directory (and version of CentOS) is deprecated. 由于只是安装tcpdump,目前临时解决方案调整了一下安装源。 1 2 3 # echo "8-stream" > /etc/yum/vars/releasever # yum clean all # yum makecache 如果未使用国内镜像也可以手工更新到 vault.centos.org 镜像地址 1 2 3 4 # cd /etc/yum.repos.d/ # sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* # sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-* # yum update -y 镜像地址更新成功后可以升级到centos stream。 ...

2022-02-03 · 1 min · 103 words · Garlic Space

centos8 过滤 syslog信息

服务器(centos8)在用户登录的时候会出现一些登录日志。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 example.com systemd[1]: Started /run/user/0 mount wrapper. example.com systemd[1]: Created slice User Slice of UID 0. example.com systemd[1]: Starting User Manager for UID 0... example.com systemd[1]: Started Session 51 of user root. example.com systemd[20871]: Starting D-Bus User Message Bus Socket. example.com systemd[20871]: Reached target Timers. example.com systemd[20871]: Reached target Paths. example.com systemd[20871]: Listening on D-Bus User Message Bus Socket. example.com systemd[20871]: Reached target Sockets. example.com systemd[20871]: Reached target Basic System. example.com systemd[20871]: Reached target Default. example.com systemd[20871]: Startup finished in 51ms. example.com systemd[1]: Started User Manager for UID 0. example.com systemd[1]: session-51.scope: Succeeded. example.com systemd[1]: Stopping User Manager for UID 0... example.com systemd[20871]: Stopped target Default. example.com systemd[20871]: Stopped target Basic System. example.com systemd[20871]: Stopped target Sockets. example.com systemd[20871]: Stopped target Paths. example.com systemd[20871]: dbus.socket: Succeeded. example.com systemd[20871]: Closed D-Bus User Message Bus Socket. example.com systemd[20871]: Reached target Shutdown. example.com systemd[20871]: Starting Exit the Session... example.com systemd[20871]: Stopped target Timers. example.com systemd[1]: user@0.service: Killing process 20967 (systemctl) with signal SIGKILL. example.com systemd[1]: user@0.service: Succeeded. example.com systemd[1]: Stopped User Manager for UID 0. example.com systemd[1]: Stopping /run/user/0 mount wrapper... example.com systemd[1]: Removed slice User Slice of UID 0. example.com systemd[1]: run-user-0.mount: Succeeded. example.com systemd[1]: user-runtime-dir@0.service: Succeeded. example.com systemd[1]: Stopped /run/user/0 mount wrapper. 通过下面命令生成rsyslog的过滤规则; 1 2 3 4 5 6 7 8 9 10 echo 'if $programname == "systemd" and ($msg contains "Started /run/$msg" or $msg contains "Starting Session" or $msg contains "Started Session" or $msg contains "Created slice User" or $msg contains "Starting User Manager" or $msg contains "Starting User" or $msg contains "Starting D-Bus" or $msg contains "Reached target" or $msg contains "Listening on D-Bus" or $msg contains "Startup finished" or $msg contains "session-" or $msg contains "Stopping User Manager" or $msg contains "Stopped target" or $msg contain "dbus.socket" or $msg contains "Stopped target " or $msg contains "Removed session" or $msg contains "Removed slice User Slice of" or $msg contains "Stopped /run/user" or $msg contains "Stopped User Manager" or $msg contains "Stopping User Slice of" ) then stop' >/etc/rsyslog.d/ignore-systemd-session-slice.conf 根据实际情况, 新增相关过滤规则即可 ...

2022-01-02 · 2 min · 385 words · Garlic Space