Files
tailscale/util/cmpver/version_test.go
Brad Fitzpatrick 5ef3713c9f cmd/vet: add subtestnames analyzer; fix all existing violations
Add a new vet analyzer that checks t.Run subtest names don't contain
characters requiring quoting when re-running via "go test -run". This
enforces the style guide rule: don't use spaces or punctuation in
subtest names.

The analyzer flags:
- Direct t.Run calls with string literal names containing spaces,
  regex metacharacters, quotes, or other problematic characters
- Table-driven t.Run(tt.name, ...) calls where tt ranges over a
  slice/map literal with bad name field values

Also fix all 978 existing violations across 81 test files, replacing
spaces with hyphens and shortening long sentence-like names to concise
hyphenated forms.

Updates #19242

Change-Id: Ib0ad96a111bd8e764582d1d4902fe2599454ab65
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2026-04-05 15:52:51 -07:00

195 lines
3.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package cmpver_test
import (
"testing"
"tailscale.com/util/cmpver"
)
func TestCompare(t *testing.T) {
tests := []struct {
name string
v1, v2 string
want int
}{
{
name: "both-empty",
want: 0,
},
{
name: "v1-empty",
v2: "1.2.3",
want: -1,
},
{
name: "v2-empty",
v1: "1.2.3",
want: 1,
},
{
name: "semver-major",
v1: "2.0.0",
v2: "1.9.9",
want: 1,
},
{
name: "semver-major",
v1: "2.0.0",
v2: "1.9.9",
want: 1,
},
{
name: "semver-minor",
v1: "1.9.0",
v2: "1.8.9",
want: 1,
},
{
name: "semver-patch",
v1: "1.9.9",
v2: "1.9.8",
want: 1,
},
{
name: "semver-equal",
v1: "1.9.8",
v2: "1.9.8",
want: 0,
},
{
name: "tailscale-major",
v1: "1.0-0",
v2: "0.97-105",
want: 1,
},
{
name: "tailscale-minor",
v1: "0.98-0",
v2: "0.97-105",
want: 1,
},
{
name: "tailscale-patch",
v1: "0.97-120",
v2: "0.97-105",
want: 1,
},
{
name: "tailscale-equal",
v1: "0.97-105",
v2: "0.97-105",
want: 0,
},
{
name: "tailscale-weird-extra-field",
v1: "0.96.1-0", // more fields == larger
v2: "0.96-105",
want: 1,
},
{
// Though ۱ and ۲ both satisfy unicode.IsNumber, our previous use
// of strconv.ParseUint with these characters would have lead us to
// panic. We're now only looking at ascii numbers, so test these are
// compared as text.
name: "only-ascii-numbers",
v1: "۱۱", // 2x EXTENDED ARABIC-INDIC DIGIT ONE
v2: "۲", // 1x EXTENDED ARABIC-INDIC DIGIT TWO
want: -1,
},
// A few specific OS version tests below.
{
name: "windows-version",
v1: "10.0.19045.3324",
v2: "10.0.18362",
want: 1,
},
{
name: "windows-11-above-10_0_22000",
v1: "10.0.22631.2262",
v2: "10.0.22000",
want: 1,
},
{
name: "android-short-version",
v1: "10",
v2: "7",
want: 1,
},
{
name: "android-longer-version",
v1: "7.1.2",
v2: "7",
want: 1,
},
{
name: "iOS-version",
v1: "15.6.1",
v2: "15.6",
want: 1,
},
{
name: "linux-short-kernel-version",
v1: "4.4.302+",
v2: "4.0",
want: 1,
},
{
name: "linux-long-kernel-version",
v1: "4.14.255-311-248.529.amzn2.x86_64",
v2: "4.0",
want: 1,
},
{
name: "freebsd-version",
v1: "14.0-CURRENT",
v2: "14",
want: 1,
},
{
name: "synology-version",
v1: "Synology 6.2.4; kernel=3.10.105",
v2: "Synology 6",
want: 1,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
got := cmpver.Compare(test.v1, test.v2)
if got != test.want {
t.Errorf("Compare(%q, %q) = %v, want %v", test.v1, test.v2, got, test.want)
}
// Reversing the comparison should reverse the outcome.
got2 := cmpver.Compare(test.v2, test.v1)
if got2 != -test.want {
t.Errorf("Compare(%q, %q) = %v, want %v", test.v2, test.v1, got2, -test.want)
}
if got, want := cmpver.Less(test.v1, test.v2), test.want < 0; got != want {
t.Errorf("Less(%q, %q) = %v, want %v", test.v1, test.v2, got, want)
}
if got, want := cmpver.Less(test.v2, test.v1), test.want > 0; got != want {
t.Errorf("Less(%q, %q) = %v, want %v", test.v2, test.v1, got, want)
}
if got, want := cmpver.LessEq(test.v1, test.v2), test.want <= 0; got != want {
t.Errorf("LessEq(%q, %q) = %v, want %v", test.v1, test.v2, got, want)
}
if got, want := cmpver.LessEq(test.v2, test.v1), test.want >= 0; got != want {
t.Errorf("LessEq(%q, %q) = %v, want %v", test.v2, test.v1, got, want)
}
// Check that version comparison does not allocate.
if n := testing.AllocsPerRun(100, func() { cmpver.Compare(test.v1, test.v2) }); n > 0 {
t.Errorf("Compare(%q, %q) got %v allocs per run", test.v1, test.v2, n)
}
})
}
}