github.com/coreos/rocket@v1.30.1-0.20200224141603-171c416fac02/rkt/image/common_test.go (about) 1 // Copyright 2015 The rkt Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package image 16 17 import ( 18 "fmt" 19 "net/url" 20 "path/filepath" 21 "testing" 22 "time" 23 24 dist "github.com/rkt/rkt/pkg/distribution" 25 ) 26 27 func TestGuessAppcOrPath(t *testing.T) { 28 tests := []struct { 29 image string 30 expectedType imageStringType 31 }{ 32 // guess obvious absolute path as a path 33 { 34 image: "/usr/libexec/rkt/stage1.aci", 35 expectedType: imageStringPath, 36 }, 37 // guess stuff with colon as a name 38 { 39 image: "example.com/stage1:1.2.3", 40 expectedType: imageStringName, 41 }, 42 // guess stuff with ./ as a path 43 { 44 image: "some/relative/../path/with/dots/file", 45 expectedType: imageStringPath, 46 }, 47 // the same 48 { 49 image: "./another/obviously/relative/path", 50 expectedType: imageStringPath, 51 }, 52 // guess stuff ending with .aci as a path 53 { 54 image: "some/relative/path/with/aci/extension.aci", 55 expectedType: imageStringPath, 56 }, 57 // guess stuff without .aci, ./ and : as a name 58 { 59 image: "example.com/stage1", 60 expectedType: imageStringName, 61 }, 62 // another try 63 { 64 image: "example.com/stage1,version=1.2.3,foo=bar", 65 expectedType: imageStringName, 66 }, 67 } 68 for _, tt := range tests { 69 guessed := guessAppcOrPath(tt.image, []string{".aci"}) 70 if tt.expectedType != guessed { 71 t.Errorf("expected %q to be guessed as %q, but got %q", tt.image, imageTypeToString(tt.expectedType), imageTypeToString(guessed)) 72 } 73 } 74 } 75 76 func imageTypeToString(imType imageStringType) string { 77 switch imType { 78 case imageStringName: 79 return "name" 80 case imageStringPath: 81 return "path" 82 default: 83 return "unknown" 84 } 85 } 86 87 func TestSignatureURLFromImageURL(t *testing.T) { 88 tests := []struct { 89 i string 90 s string 91 }{ 92 { 93 i: "http://example.com/image", 94 s: "http://example.com/image.aci.asc", 95 }, 96 { 97 i: "http://example.com/image.aci", 98 s: "http://example.com/image.aci.asc", 99 }, 100 { 101 i: "http://example.com/image.aci?foo=bar&baz=quux#blah", 102 s: "http://example.com/image.aci.asc?foo=bar&baz=quux#blah", 103 }, 104 } 105 for _, tt := range tests { 106 iu, err := url.Parse(tt.i) 107 if err != nil { 108 t.Errorf("failed to parse %q as an image URL: %v", tt.i, err) 109 continue 110 } 111 su, err := url.Parse(tt.s) 112 if err != nil { 113 t.Errorf("failed to parse %q as a signature URL: %v", tt.s, err) 114 continue 115 } 116 got := ascURLFromImgURL(iu) 117 if su.String() != got.String() { 118 t.Errorf("expected signature URL for image URL %q to be %q, but got %q", iu.String(), su.String(), got.String()) 119 } 120 } 121 } 122 123 func TestSignaturePathFromImagePath(t *testing.T) { 124 tests := []struct { 125 i string 126 s string 127 }{ 128 { 129 i: "/some/path/to/image", 130 s: "/some/path/to/image.aci.asc", 131 }, 132 { 133 i: "/some/path/to/image.aci", 134 s: "/some/path/to/image.aci.asc", 135 }, 136 } 137 for _, tt := range tests { 138 got := ascPathFromImgPath(tt.i) 139 if tt.s != got { 140 t.Errorf("expected signature path for image path %q to be %q, but got %q", tt.i, tt.s, got) 141 } 142 } 143 } 144 145 func TestUseCached(t *testing.T) { 146 tests := []struct { 147 age int 148 use bool 149 }{ 150 { 151 age: -11, 152 use: false, 153 }, 154 { 155 age: -1, 156 use: true, 157 }, 158 } 159 maxAge := 10 160 for _, tt := range tests { 161 age := time.Now().Add(time.Duration(tt.age) * time.Second) 162 got := useCached(age, maxAge) 163 if got != tt.use { 164 t.Errorf("expected useCached(%v, %v) to return %v, but it returned %v", age, maxAge, tt.use, got) 165 } 166 } 167 } 168 169 func TestDistFromImageString(t *testing.T) { 170 relPath1 := "some/relative/../path/with/dots/file.aci" 171 absPath1, err := filepath.Abs(relPath1) 172 if err != nil { 173 174 t.Fatalf("unexpected error: %v", err) 175 } 176 relPath2 := "some/relative/../path/with/dots/file" 177 absPath2, err := filepath.Abs(relPath2) 178 if err != nil { 179 t.Fatalf("unexpected error: %v", err) 180 } 181 182 tests := []struct { 183 in string 184 distString string 185 err error 186 }{ 187 // Appc 188 { 189 "example.com/app01", 190 "cimd:appc:v=0:example.com/app01", 191 nil, 192 }, 193 { 194 "example.com/app01:v1.0.0", 195 "cimd:appc:v=0:example.com/app01?version=v1.0.0", 196 nil, 197 }, 198 { 199 "example.com/app01:v1.0.0,label01=?&*/", 200 "cimd:appc:v=0:example.com/app01?label01=%3F%26%2A%2F&version=v1.0.0", 201 nil, 202 }, 203 { 204 "some-image-name", 205 "cimd:appc:v=0:some-image-name", 206 nil, 207 }, 208 { 209 "some-image-name:v1.0.0", 210 "cimd:appc:v=0:some-image-name?version=v1.0.0", 211 nil, 212 }, 213 { 214 "some-image-name:f6432b725a9a5f27eaecfa47a0cbab3c0ea00f22", 215 "cimd:appc:v=0:some-image-name?version=f6432b725a9a5f27eaecfa47a0cbab3c0ea00f22", 216 nil, 217 }, 218 // ACIArchive 219 { 220 "file:///absolute/path/to/file.aci", 221 "cimd:aci-archive:v=0:file%3A%2F%2F%2Fabsolute%2Fpath%2Fto%2Ffile.aci", 222 nil, 223 }, 224 { 225 "/absolute/path/to/file.aci", 226 "cimd:aci-archive:v=0:file%3A%2F%2F%2Fabsolute%2Fpath%2Fto%2Ffile.aci", 227 nil, 228 }, 229 { 230 relPath1, 231 "cimd:aci-archive:v=0:" + url.QueryEscape("file://"+absPath1), 232 nil, 233 }, 234 { 235 "https://example.com/app.aci", 236 "cimd:aci-archive:v=0:https%3A%2F%2Fexample.com%2Fapp.aci", 237 nil, 238 }, 239 // Path with no .aci extension 240 { 241 "/absolute/path/to/file", 242 "", 243 fmt.Errorf("invalid image string %q", "file:///absolute/path/to/file"), 244 }, 245 { 246 "/absolute/path/to/file.tar", 247 "", 248 fmt.Errorf("invalid image string %q", "file:///absolute/path/to/file.tar"), 249 }, 250 { 251 relPath2, 252 "", 253 fmt.Errorf("invalid image string %q", "file://"+absPath2), 254 }, 255 // Docker 256 { 257 "docker:busybox", 258 "cimd:docker:v=0:registry-1.docker.io/library/busybox:latest", 259 nil, 260 }, 261 { 262 "docker://busybox", 263 "cimd:docker:v=0:registry-1.docker.io/library/busybox:latest", 264 nil, 265 }, 266 { 267 "docker:busybox:latest", 268 "cimd:docker:v=0:registry-1.docker.io/library/busybox:latest", 269 nil, 270 }, 271 { 272 "docker://busybox:latest", 273 "cimd:docker:v=0:registry-1.docker.io/library/busybox:latest", 274 nil, 275 }, 276 { 277 "docker:busybox:1.0", 278 "cimd:docker:v=0:registry-1.docker.io/library/busybox:1.0", 279 nil, 280 }, 281 { 282 "docker:busybox@sha256:a59906e33509d14c036c8678d687bd4eec81ed7c4b8ce907b888c607f6a1e0e6", 283 "cimd:docker:v=0:registry-1.docker.io/library/busybox@sha256:a59906e33509d14c036c8678d687bd4eec81ed7c4b8ce907b888c607f6a1e0e6", 284 nil, 285 }, 286 { 287 "docker:myregistry.example.com:4000/busybox", 288 "cimd:docker:v=0:myregistry.example.com:4000/busybox:latest", 289 nil, 290 }, 291 { 292 "docker:myregistry.example.com:4000/busybox", 293 "cimd:docker:v=0:myregistry.example.com:4000/busybox:latest", 294 nil, 295 }, 296 { 297 "docker:myregistry.example.com:4000/busybox:1.0", 298 "cimd:docker:v=0:myregistry.example.com:4000/busybox:1.0", 299 nil, 300 }, 301 } 302 303 for _, tt := range tests { 304 d, err := DistFromImageString(tt.in) 305 if err != nil { 306 if tt.err == nil { 307 t.Fatalf("unexpected error: %v", err) 308 } 309 if tt.err.Error() != err.Error() { 310 t.Fatalf("expected error %v, but got error %v", tt.err, err) 311 } 312 continue 313 } else { 314 if tt.err != nil { 315 t.Fatalf("expected error %v, but got nil error", tt.err) 316 } 317 } 318 td, err := dist.Parse(tt.distString) 319 if err != nil { 320 t.Fatalf("unexpected error: %v", err) 321 } 322 if !d.Equals(td) { 323 t.Fatalf("expected identical distribution but got %q != %q", tt.distString, d.CIMD().String()) 324 } 325 } 326 327 }