mirror of
				https://github.com/tailscale/tailscale.git
				synced 2025-10-31 08:11:32 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			195 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			195 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright (c) Tailscale Inc & AUTHORS
 | ||
| // 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 is everything 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)
 | ||
| 			}
 | ||
| 		})
 | ||
| 	}
 | ||
| }
 |