1:gomock 为官方开发的工具:https://github.com/golang/mock
主要目的是用来mock interface的,自动生成一个同样的实现,这样在测试的时候不用依赖真实的对象
特别像连接一些外部资源的时候比较好用。

2:gomonkey https://github.com/agiledragon/gomonkey 一个注入工具
可以注入函数、外部对象的方法。

原始代码,大致:

func (ci *CheckIP) CheckAllowIP(r *http.Request) (msg string, code int) {
	msg, code = "", 0
	ip := common.GetClientIP(r, Conf.Server.ClientIPMode)
	redisConn := RedisPool.Get()
	defer redisConn.Close()
	result, _ := redis.String(redisConn.Do("GET", ip))
	if result != "" {
		code = 400
		msg = "exist"
	}
	return
}

注入方法:

继续阅读

在单元测试的时候经常需要判断对比是否一致,在遇到时间字段的时候会出现看着字面一样实际

提示不一致的情况,经过分析是时间字段时区导致的。

 

一般我们在连接DB的代码里面都会指定时间为GMT+8的时区,在单元测试的时候也需要把要匹配

的时间对象指定为GMT+8的时区。

timeLocation, _ := time.LoadLocation("Asia/Chongqing")

wantDate, _ = time.ParseInLocation("2006-01-02 15:04:05", "2019-08-08 12:12:12", timeLocation)

在调试过程中可以使用fmt.Printf("#v",struct) 来打印关于struct更细节的信息

golang xml处理函数目前常规的应用没有问题,主要利用xml.Marshal和xml.Unmarshal。
不能生成自关闭标签,能解析自关闭标签。遇到命名空间的时候比较头大,解析和生成xml不能用一个结构,必须定义成2个。

1:获取字段属性

func main() {
    d := `<result code="1000"><msg>Command completed successfully.</msg></result>`
    type result struct {
        Code     int    `xml:"code,attr"`
        Msg      string `xml:"msg"`
    }
    abc := result{}
    xml.Unmarshal([]byte(d),&amp;abc)
    fmt.Printf("%+v\n",abc)
}
    //{Code:1000 Msg:Command completed successfully.}

2:节点带有属性和内容的获取方式

func main() {
    d := `<result code="1000"><period unit="y">1</period></result>`
    type result struct {
        Period struct{
            Unit string `xml:"unit,attr"`
            Value int `xml:",chardata"`
        } `xml:"period"`
    }
    abc := result{}
    xml.Unmarshal([]byte(d),&amp;abc)
    fmt.Printf("%+v\n",abc)
}
    //{Period:{Unit:y Value:1}}

3:如果有节点一样,仅仅是命名空间不一样的处理方式

继续阅读

在用golang处理xml 命名空间属性,可能是个bug,golang 1.10.1

func main() {
 str :=`<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd">
 <hello />
</epp>`
 doc:=xml.NewDecoder(strings.NewReader(str))
 for {
 t, err := doc.Token()
 if err!=nil{
     print(err.Error())
     break
 }
 switch to := t.(type) {
 case xml.StartElement:
     for _,v:=range to.Copy().Attr{
     fmt.Printf("space:%s--local:%s---value:%s\n",v.Name.Space,v.Name.Local,v.Value)
 }
 default:
 }
 }
}

得到的结果:

space:--local:xmlns---value:urn:ietf:params:xml:ns:epp-1.0
space:xmlns--local:xsi---value:http://www.w3.org/2001/XMLSchema-instance
space:http://www.w3.org/2001/XMLSchema-instance--local:schemaLocation---value:urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd

在解析 xsi:schemaLocation 这个名称的时候返回的不对了。感觉是个BUG,有新的发现在更新。

这里使用的是官方的包管理工具dep  https://github.com/golang/dep

背景 gitlab 10.5.6,gitlab_ci,golang 1.10.1,dep v0.4.1

1:安装,直接在github下载二进制文件,放入系统的path目录即可

2:遇到的问题

2.1 go get gitlab项目失败

git config --global url."[email protected]:".insteadOf "https://git.ciphp.com/" 使用ssh的方式替代https的模式,这样可以用证书拉项目

2.2 dep init 不能在软链接目录执行

暂时无解,请到gopath非软链接目录执行

2.3 dep ensure is not within a known GOPATH/src

如果登录到gitlab ci机器,能手工执行成功,修改.gitalb-ci.yml执行脚本的pwd环境变量<

2019-05-29 更新

现在使用官方的go mod来管理包,比dep来得方便

手头有个乐视的路由器,想着刷个openwrt玩玩插件,参考地址http://www.right.com.cn/forum/thread-172877-1-1.html 还有一些其他资料就准备开刷。

第1步资料已经变动,http://downloads.openwrt.org/attitude_adjustment/12.09-rc1/ar71xx/generic/packages/Packages.gz.
这个地址已经变为http://downloads.openwrt.org/attitude_adjustment/12.09/ar71xx/generic/packages/Packages.gz. 在安装页面有个配置选项,直接在里面修改就行[不过我后面刷了另一个包,不确认这个是否必须]

继续阅读

php偏移量16个0

openssl_encrypt($xml,'AES-128-CBC',$key, false, hex2bin('00000000000000000000000000000000'));

//java代码是服务提供方写的,目前知道这样写的对方能解出来,不懂java就不写代码了.

golang

package main

import (
"bytes"
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"fmt"
"io"
"log"
"os"
)

var iv = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
//必须这样写,如果写成[]byte("16个0")会丢失前面16个字节

func main() {
TestCBCAES()
}

func TestCBCAES() {
key := []byte("IHqnFXMNhpzYNLOU")
data := "xmlssssss"
result, err := AesEncrypt([]byte(data), key)
if err != nil {
panic(err)
}
origData, err := AesDecrypt(result, key)
if err != nil {
panic(err)
}
fmt.Println(string(origData))
}

func AesEncrypt(origData, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
blockSize := block.BlockSize()
origData = PKCS5Padding(origData, blockSize)
blockMode := cipher.NewCBCEncrypter(block, iv)
crypted := make([]byte, len(origData))
blockMode.CryptBlocks(crypted, origData)
return crypted, nil
}

func AesDecrypt(crypted, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
//blockSize := block.BlockSize()
blockMode := cipher.NewCBCDecrypter(block, iv)
origData := make([]byte, len(crypted))
// origData := crypted
blockMode.CryptBlocks(origData, crypted)
origData = PKCS5UnPadding(origData)
return origData, nil
}

func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}

func PKCS5UnPadding(origData []byte) []byte {
length := len(origData)
// remove the last byte
unpadding := int(origData[length-1])
return origData[:(length - unpadding)]

}

golang代码参考,修改了偏移量的方式,可能跟服务端实现的方式有关系

如何讓 AES 在 Golang 與 Android(Java) 得到一致的加解密結果

GO项目跑整个项目的覆盖率

gitlab-ci.sh 内容如下

set -e echo "mode: atomic" > coverage.txt

for d in $(go list ./... | grep -v vendor | grep -v doc); do
go test -race -coverprofile=profile.out $d
if [ -f profile.out ]; then
cat profile.out | grep -v statements | grep -v atomic >> coverage.txt
rm profile.out
fi done

go tool cover -func=coverage.txt

go 1.10 之后建议使用如下代码

set -e
go test -race -coverprofile=coverage.txt $(go list ./... | grep -v "vendor" | grep -v "doc")
go tool cover -func=coverage.txt

gitlab页面设置

导航到页面settings/ci_cd 展开节点:General pipelines settings-->Test coverage parsing

输入 total:\s+\(statements\)\s+(\d+.\d+)%

ELK是elasticsearch、kibana、logstas组合的简称,是一套强大的日志处理系统, grafana是一款golang开发的数据显示软件,支持多种数据源,UI漂亮,支持报警

软件下载&安装

es下载地址 https://www.elastic.co/downloads/elasticsearch

kibana https://www.elastic.co/downloads/kibana

logstash https://www.elastic.co/downloads/logstash

filebeat https://www.elastic.co/downloads/beats

grafana https://grafana.com/grafana/download

安装比较简单,直接安装官方说明装就可以了。

继续阅读