前段时间与团队成员做了一个线上规则库版本管理后台,用以在客户端在线升级规则库。
规则库的升级方式,其实就是比对规则库版本信息,将当前版本规则库,升级到更新的规则库版本。
在上周发版测试中,发现规则库升级一直报异常,虽然最后排查到问题是出在规则库管理流程上,即线上管理后台并没有上传相关版本的规则库,
但我觉得仍有必要以自己的理解及认识,去重新实现这个版本比对工具。
以下是 golang 的代码实现,并附上测试用例
// CompareVersion compare oldv and newv, if oldv > newv return 1
// if oldv < newv return -1, otherwise return 0, and return -999 if
// version is bad format
func CompareVersion(oldv, newv string) int {
if strings.Compare(oldv, newv) == 0 {
return 0
}
var (
oldvs = strings.Split(oldv, ".")
newvs = strings.Split(newv, ".")
appendEle = func(t *[]string, c int) {
for i := 0; i < c; i++ {
*t = append(*t, "0")
}
}
)
// if len(oldvs) not equal len(newvs), then make up "0" for the short
if len(oldvs) >= len(newvs) {
appendEle(&newvs, len(oldvs) - len(newvs))
} else {
appendEle(&oldvs, len(newvs) - len(oldvs))
}
// compare first element, if not equal, then return ret, or continue compare
var firstCompareResult = strings.Compare(oldvs[0], newvs[0])
if firstCompareResult != 0 {
return firstCompareResult
}
// compare the other element
for i := 1; i <= len(newvs)-1; i++ {
var (
err error
ov, nv int
)
ov, err = strconv.Atoi(oldvs[i])
if err != nil {
log.Printf("Bad format %+v \n", oldvs[i])
return -999
}
nv, err = strconv.Atoi(newvs[i])
if err != nil {
log.Printf("Bad format %+v \n", newvs[i])
return -999
}
if ov == nv {
continue
} else if ov > nv {
return 1
} else {
return -1
}
}
return 0
}
测试用例及测试结果
func TestCompareVersion(t *testing.T) {
var versionTestSlice = [][]string{
{">", "2.2.1", "2.2.0"},
{">", "2.2.1", "2.1.9"},
{"=", "2.2.1", "2.2.01"},
{">", "2.2", "2.1.1"},
{"<", "2.2", "2.2.1"},
{"<", "2.2.3.1", "2.2.3.5"},
{">", "2.2.3.1", "2.2.3.0"},
{"<", "2.2.3.4", "2.2.4.4.5"},
{"<", "2.2.3.4.5.6", "2.2.3.4.5.12"},
{">", "2.2.3.4.5.6", "2.2.2.4.5.12"},
{">", "3.0.0.1", "3.0.0.0.1"},
{">", "v2.2.1", "v2.2.0"},
{">", "v2.2.1", "v2.1.9"},
{"=", "v2.2.1", "v2.2.01"},
{">", "v2.2", "v2.1.1"},
{"<", "v2.2", "v2.2.1"},
{"<", "v2.2.3.1", "v2.2.3.5"},
{">", "v3.0.1", "v2.3.5"},
{"=", "3.1", "3.1."},
}
for _, v := range versionTestSlice {
t.Logf("Expect %s %s %s -> %d", v[1], v[0], v[2], CompareVersion(v[1], v[2]))
}
}
输出如下:
❯ go test -v .\compare_version_test.go .\compare_version.go
=== RUN TestCompareVersion
2020/06/18 15:44:44 Bad format
--- PASS: TestCompareVersion (0.02s)
compare_version_test.go:28: Expect 2.2.1 > 2.2.0 -> 1
compare_version_test.go:28: Expect 2.2.1 > 2.1.9 -> 1
compare_version_test.go:28: Expect 2.2.1 = 2.2.01 -> 0
compare_version_test.go:28: Expect 2.2 > 2.1.1 -> 1
compare_version_test.go:28: Expect 2.2 < 2.2.1 -> -1
compare_version_test.go:28: Expect 2.2.3.1 < 2.2.3.5 -> -1
compare_version_test.go:28: Expect 2.2.3.1 > 2.2.3.0 -> 1
compare_version_test.go:28: Expect 2.2.3.4 < 2.2.4.4.5 -> -1
compare_version_test.go:28: Expect 2.2.3.4.5.6 < 2.2.3.4.5.12 -> -1
compare_version_test.go:28: Expect 2.2.3.4.5.6 > 2.2.2.4.5.12 -> 1
compare_version_test.go:28: Expect 3.0.0.1 > 3.0.0.0.1 -> 1
compare_version_test.go:28: Expect v2.2.1 > v2.2.0 -> 1
compare_version_test.go:28: Expect v2.2.1 > v2.1.9 -> 1
compare_version_test.go:28: Expect v2.2.1 = v2.2.01 -> 0
compare_version_test.go:28: Expect v2.2 > v2.1.1 -> 1
compare_version_test.go:28: Expect v2.2 < v2.2.1 -> -1
compare_version_test.go:28: Expect v2.2.3.1 < v2.2.3.5 -> -1
compare_version_test.go:28: Expect v3.0.1 > v2.3.5 -> 1
compare_version_test.go:28: Expect 3.1 = 3.1. -> -999
PASS
ok command-line-arguments 0.384s