@@ -28,13 +28,117 @@ import (
2828 "os"
2929 "path"
3030 "runtime"
31+ "strings"
32+ "testing"
3133
3234 . "github.com/onsi/ginkgo/v2"
3335 . "github.com/onsi/gomega"
3436 "github.com/onsi/gomega/ghttp"
3537 "sigs.k8s.io/yaml"
3638)
3739
40+ func TestParseKubernetesVersion (t * testing.T ) {
41+ t .Parallel ()
42+
43+ testCases := []struct {
44+ name string
45+ inputs []string
46+
47+ expectError string
48+ expectExact bool
49+ expectSeriesMajor uint
50+ expectSeriesMinor uint
51+ }{
52+ {
53+ name : `SemVer and "v" prefix are exact` ,
54+ inputs : []string {
55+ "1.2.3" , "v1.2.3" , "v1.30.2" , "v1.31.0-beta.0" , "v1.33.0-alpha.2" ,
56+ },
57+ expectExact : true ,
58+ },
59+ {
60+ name : "empty string is not a version" ,
61+ inputs : []string {"" },
62+ expectError : "could not parse" ,
63+ },
64+ {
65+ name : "leading zeroes are not a version" ,
66+ inputs : []string {
67+ "01.2.0" , "00001.2.3" , "1.2.03" , "v01.02.0003" ,
68+ },
69+ expectError : "could not parse" ,
70+ },
71+ {
72+ name : "weird stuff is not a version" ,
73+ inputs : []string {
74+ "asdf" , "version" , "vegeta4" , "the.1" , "2ne1" , "=7.8.9" , "10.x" , "*" ,
75+ "0.0001" , "1.00002" , "v1.2anything" , "1.2.x" , "1.2.z" , "1.2.*" ,
76+ },
77+ expectError : "could not parse" ,
78+ },
79+ {
80+ name : "one number is not a version" ,
81+ inputs : []string {
82+ "1" , "v1" , "v001" , "1." , "v1." , "1.x" ,
83+ },
84+ expectError : "could not parse" ,
85+ },
86+ {
87+ name : "two numbers are a release series" ,
88+ inputs : []string {"0.1" , "v0.1" },
89+
90+ expectSeriesMajor : 0 ,
91+ expectSeriesMinor : 1 ,
92+ },
93+ {
94+ name : "two numbers are a release series" ,
95+ inputs : []string {"1.2" , "v1.2" },
96+
97+ expectSeriesMajor : 1 ,
98+ expectSeriesMinor : 2 ,
99+ },
100+ }
101+
102+ for _ , tc := range testCases {
103+ t .Run (tc .name , func (t * testing.T ) {
104+ for _ , input := range tc .inputs {
105+ exact , major , minor , err := parseKubernetesVersion (input )
106+
107+ if tc .expectError != "" && err == nil {
108+ t .Errorf ("expected error %q, got none" , tc .expectError )
109+ }
110+ if tc .expectError != "" && ! strings .Contains (err .Error (), tc .expectError ) {
111+ t .Errorf ("expected error %q, got %q" , tc .expectError , err )
112+ }
113+ if tc .expectError == "" && err != nil {
114+ t .Errorf ("expected no error, got %q" , err )
115+ continue
116+ }
117+
118+ if tc .expectExact {
119+ if expected := strings .TrimPrefix (input , "v" ); exact != expected {
120+ t .Errorf ("expected canonical %q for %q, got %q" , expected , input , exact )
121+ }
122+ if major != 0 || minor != 0 {
123+ t .Errorf ("expected no release series for %q, got (%v, %v)" , input , major , minor )
124+ }
125+ continue
126+ }
127+
128+ if major != tc .expectSeriesMajor {
129+ t .Errorf ("expected major %v for %q, got %v" , tc .expectSeriesMajor , input , major )
130+ }
131+ if minor != tc .expectSeriesMinor {
132+ t .Errorf ("expected minor %v for %q, got %v" , tc .expectSeriesMinor , input , minor )
133+ }
134+ if exact != "" {
135+ t .Errorf ("expected no canonical version for %q, got %q" , input , exact )
136+ }
137+ }
138+ })
139+ }
140+ }
141+
38142var _ = Describe ("Test download binaries" , func () {
39143 var downloadDirectory string
40144 var server * ghttp.Server
@@ -68,11 +172,11 @@ var _ = Describe("Test download binaries", func() {
68172 Expect (actualFiles ).To (ConsistOf ("some-file" ))
69173 })
70174
71- It ("should download v1.32.0 binaries" , func (ctx SpecContext ) {
175+ It ("should download binaries of an exact version " , func (ctx SpecContext ) {
72176 apiServerPath , etcdPath , kubectlPath , err := downloadBinaryAssets (ctx , downloadDirectory , "v1.31.0" , fmt .Sprintf ("http://%s/%s" , server .Addr (), "envtest-releases.yaml" ))
73177 Expect (err ).ToNot (HaveOccurred ())
74178
75- // Verify latest stable version (v1.32 .0) was downloaded
179+ // Verify exact version (v1.31 .0) was downloaded
76180 versionDownloadDirectory := path .Join (downloadDirectory , fmt .Sprintf ("1.31.0-%s-%s" , runtime .GOOS , runtime .GOARCH ))
77181 Expect (apiServerPath ).To (Equal (path .Join (versionDownloadDirectory , "kube-apiserver" )))
78182 Expect (etcdPath ).To (Equal (path .Join (versionDownloadDirectory , "etcd" )))
@@ -86,6 +190,38 @@ var _ = Describe("Test download binaries", func() {
86190 }
87191 Expect (actualFiles ).To (ConsistOf ("some-file" ))
88192 })
193+
194+ It ("should download binaries of latest stable version of a release series" , func (ctx SpecContext ) {
195+ apiServerPath , etcdPath , kubectlPath , err := downloadBinaryAssets (ctx , downloadDirectory , "1.31" , fmt .Sprintf ("http://%s/%s" , server .Addr (), "envtest-releases.yaml" ))
196+ Expect (err ).ToNot (HaveOccurred ())
197+
198+ // Verify stable version (v1.31.4) was downloaded
199+ versionDownloadDirectory := path .Join (downloadDirectory , fmt .Sprintf ("1.31.4-%s-%s" , runtime .GOOS , runtime .GOARCH ))
200+ Expect (apiServerPath ).To (Equal (path .Join (versionDownloadDirectory , "kube-apiserver" )))
201+ Expect (etcdPath ).To (Equal (path .Join (versionDownloadDirectory , "etcd" )))
202+ Expect (kubectlPath ).To (Equal (path .Join (versionDownloadDirectory , "kubectl" )))
203+
204+ dirEntries , err := os .ReadDir (versionDownloadDirectory )
205+ Expect (err ).ToNot (HaveOccurred ())
206+ var actualFiles []string
207+ for _ , e := range dirEntries {
208+ actualFiles = append (actualFiles , e .Name ())
209+ }
210+ Expect (actualFiles ).To (ConsistOf ("some-file" ))
211+ })
212+
213+ It ("should error when the asset version is not a version" , func (ctx SpecContext ) {
214+ _ , _ , _ , err := downloadBinaryAssets (ctx , downloadDirectory , "wonky" , fmt .Sprintf ("http://%s/%s" , server .Addr (), "envtest-releases.yaml" ))
215+ Expect (err ).To (MatchError (`could not parse "wonky" as version` ))
216+ })
217+
218+ It ("should error when the asset version is not in the index" , func (ctx SpecContext ) {
219+ _ , _ , _ , err := downloadBinaryAssets (ctx , downloadDirectory , "v1.5.0" , fmt .Sprintf ("http://%s/%s" , server .Addr (), "envtest-releases.yaml" ))
220+ Expect (err ).To (MatchError ("failed to find envtest binaries for version v1.5.0" ))
221+
222+ _ , _ , _ , err = downloadBinaryAssets (ctx , downloadDirectory , "v1.5" , fmt .Sprintf ("http://%s/%s" , server .Addr (), "envtest-releases.yaml" ))
223+ Expect (err ).To (MatchError ("failed to find latest stable version from index: index does not have 1.5 stable versions" ))
224+ })
89225})
90226
91227var (
@@ -100,6 +236,15 @@ var (
100236 "envtest-v1.32.0-linux-s390x.tar.gz" : {},
101237 "envtest-v1.32.0-windows-amd64.tar.gz" : {},
102238 },
239+ "v1.31.4" : map [string ]archive {
240+ "envtest-v1.31.4-darwin-amd64.tar.gz" : {},
241+ "envtest-v1.31.4-darwin-arm64.tar.gz" : {},
242+ "envtest-v1.31.4-linux-amd64.tar.gz" : {},
243+ "envtest-v1.31.4-linux-arm64.tar.gz" : {},
244+ "envtest-v1.31.4-linux-ppc64le.tar.gz" : {},
245+ "envtest-v1.31.4-linux-s390x.tar.gz" : {},
246+ "envtest-v1.31.4-windows-amd64.tar.gz" : {},
247+ },
103248 "v1.31.0" : map [string ]archive {
104249 "envtest-v1.31.0-darwin-amd64.tar.gz" : {},
105250 "envtest-v1.31.0-darwin-arm64.tar.gz" : {},
0 commit comments