github.com/iamthemuffinman/packer@v0.9.1-0.20160314165629-d0037dddb929/common/download_test.go (about) 1 package common 2 3 import ( 4 "crypto/md5" 5 "encoding/hex" 6 "fmt" 7 "io/ioutil" 8 "net/http" 9 "net/http/httptest" 10 "os" 11 "testing" 12 ) 13 14 func TestDownloadClientVerifyChecksum(t *testing.T) { 15 tf, err := ioutil.TempFile("", "packer") 16 if err != nil { 17 t.Fatalf("tempfile error: %s", err) 18 } 19 defer os.Remove(tf.Name()) 20 21 // "foo" 22 checksum, err := hex.DecodeString("acbd18db4cc2f85cedef654fccc4a4d8") 23 if err != nil { 24 t.Fatalf("decode err: %s", err) 25 } 26 27 // Write the file 28 tf.Write([]byte("foo")) 29 tf.Close() 30 31 config := &DownloadConfig{ 32 Hash: md5.New(), 33 Checksum: checksum, 34 } 35 36 d := NewDownloadClient(config) 37 result, err := d.VerifyChecksum(tf.Name()) 38 if err != nil { 39 t.Fatalf("Verify err: %s", err) 40 } 41 42 if !result { 43 t.Fatal("didn't verify") 44 } 45 } 46 47 func TestDownloadClient_basic(t *testing.T) { 48 tf, _ := ioutil.TempFile("", "packer") 49 tf.Close() 50 os.Remove(tf.Name()) 51 52 ts := httptest.NewServer(http.FileServer(http.Dir("./test-fixtures/root"))) 53 defer ts.Close() 54 55 client := NewDownloadClient(&DownloadConfig{ 56 Url: ts.URL + "/basic.txt", 57 TargetPath: tf.Name(), 58 }) 59 path, err := client.Get() 60 if err != nil { 61 t.Fatalf("err: %s", err) 62 } 63 64 raw, err := ioutil.ReadFile(path) 65 if err != nil { 66 t.Fatalf("err: %s", err) 67 } 68 69 if string(raw) != "hello\n" { 70 t.Fatalf("bad: %s", string(raw)) 71 } 72 } 73 74 func TestDownloadClient_checksumBad(t *testing.T) { 75 checksum, err := hex.DecodeString("b2946ac92492d2347c6235b4d2611184") 76 if err != nil { 77 t.Fatalf("err: %s", err) 78 } 79 80 tf, _ := ioutil.TempFile("", "packer") 81 tf.Close() 82 os.Remove(tf.Name()) 83 84 ts := httptest.NewServer(http.FileServer(http.Dir("./test-fixtures/root"))) 85 defer ts.Close() 86 87 client := NewDownloadClient(&DownloadConfig{ 88 Url: ts.URL + "/basic.txt", 89 TargetPath: tf.Name(), 90 Hash: HashForType("md5"), 91 Checksum: checksum, 92 }) 93 if _, err := client.Get(); err == nil { 94 t.Fatal("should error") 95 } 96 } 97 98 func TestDownloadClient_checksumGood(t *testing.T) { 99 checksum, err := hex.DecodeString("b1946ac92492d2347c6235b4d2611184") 100 if err != nil { 101 t.Fatalf("err: %s", err) 102 } 103 104 tf, _ := ioutil.TempFile("", "packer") 105 tf.Close() 106 os.Remove(tf.Name()) 107 108 ts := httptest.NewServer(http.FileServer(http.Dir("./test-fixtures/root"))) 109 defer ts.Close() 110 111 client := NewDownloadClient(&DownloadConfig{ 112 Url: ts.URL + "/basic.txt", 113 TargetPath: tf.Name(), 114 Hash: HashForType("md5"), 115 Checksum: checksum, 116 }) 117 path, err := client.Get() 118 if err != nil { 119 t.Fatalf("err: %s", err) 120 } 121 122 raw, err := ioutil.ReadFile(path) 123 if err != nil { 124 t.Fatalf("err: %s", err) 125 } 126 127 if string(raw) != "hello\n" { 128 t.Fatalf("bad: %s", string(raw)) 129 } 130 } 131 132 func TestDownloadClient_checksumNoDownload(t *testing.T) { 133 checksum, err := hex.DecodeString("3740570a423feec44c2a759225a9fcf9") 134 if err != nil { 135 t.Fatalf("err: %s", err) 136 } 137 138 ts := httptest.NewServer(http.FileServer(http.Dir("./test-fixtures/root"))) 139 defer ts.Close() 140 141 client := NewDownloadClient(&DownloadConfig{ 142 Url: ts.URL + "/basic.txt", 143 TargetPath: "./test-fixtures/root/another.txt", 144 Hash: HashForType("md5"), 145 Checksum: checksum, 146 }) 147 path, err := client.Get() 148 if err != nil { 149 t.Fatalf("err: %s", err) 150 } 151 152 raw, err := ioutil.ReadFile(path) 153 if err != nil { 154 t.Fatalf("err: %s", err) 155 } 156 157 // If this says "hello" it means we downloaded it. We faked out 158 // the downloader above by giving it the checksum for "another", but 159 // requested the download of "hello" 160 if string(raw) != "another\n" { 161 t.Fatalf("bad: %s", string(raw)) 162 } 163 } 164 165 func TestDownloadClient_resume(t *testing.T) { 166 tf, _ := ioutil.TempFile("", "packer") 167 tf.Write([]byte("w")) 168 tf.Close() 169 170 ts := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { 171 if r.Method == "HEAD" { 172 rw.Header().Set("Accept-Ranges", "bytes") 173 rw.WriteHeader(204) 174 return 175 } 176 177 http.ServeFile(rw, r, "./test-fixtures/root/basic.txt") 178 })) 179 defer ts.Close() 180 181 client := NewDownloadClient(&DownloadConfig{ 182 Url: ts.URL, 183 TargetPath: tf.Name(), 184 }) 185 path, err := client.Get() 186 if err != nil { 187 t.Fatalf("err: %s", err) 188 } 189 190 raw, err := ioutil.ReadFile(path) 191 if err != nil { 192 t.Fatalf("err: %s", err) 193 } 194 195 if string(raw) != "wello\n" { 196 t.Fatalf("bad: %s", string(raw)) 197 } 198 } 199 200 func TestDownloadClient_usesDefaultUserAgent(t *testing.T) { 201 tf, err := ioutil.TempFile("", "packer") 202 if err != nil { 203 t.Fatalf("tempfile error: %s", err) 204 } 205 defer os.Remove(tf.Name()) 206 207 defaultUserAgent := "" 208 asserted := false 209 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 210 if defaultUserAgent == "" { 211 defaultUserAgent = r.UserAgent() 212 } else { 213 incomingUserAgent := r.UserAgent() 214 if incomingUserAgent != defaultUserAgent { 215 t.Fatalf("Expected user agent %s, got: %s", defaultUserAgent, incomingUserAgent) 216 } 217 218 asserted = true 219 } 220 })) 221 222 req, err := http.NewRequest("GET", server.URL, nil) 223 if err != nil { 224 t.Fatal(err) 225 } 226 227 httpClient := &http.Client{ 228 Transport: &http.Transport{ 229 Proxy: http.ProxyFromEnvironment, 230 }, 231 } 232 233 _, err = httpClient.Do(req) 234 if err != nil { 235 t.Fatal(err) 236 } 237 238 config := &DownloadConfig{ 239 Url: server.URL, 240 TargetPath: tf.Name(), 241 } 242 243 client := NewDownloadClient(config) 244 _, err = client.Get() 245 if err != nil { 246 t.Fatal(err) 247 } 248 249 if !asserted { 250 t.Fatal("User-Agent never observed") 251 } 252 } 253 254 func TestDownloadClient_setsUserAgent(t *testing.T) { 255 tf, err := ioutil.TempFile("", "packer") 256 if err != nil { 257 t.Fatalf("tempfile error: %s", err) 258 } 259 defer os.Remove(tf.Name()) 260 261 asserted := false 262 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 263 asserted = true 264 if r.UserAgent() != "fancy user agent" { 265 t.Fatalf("Expected useragent fancy user agent, got: %s", r.UserAgent()) 266 } 267 })) 268 config := &DownloadConfig{ 269 Url: server.URL, 270 TargetPath: tf.Name(), 271 UserAgent: "fancy user agent", 272 } 273 274 client := NewDownloadClient(config) 275 _, err = client.Get() 276 if err != nil { 277 t.Fatal(err) 278 } 279 280 if !asserted { 281 t.Fatal("HTTP request never made") 282 } 283 } 284 285 func TestHashForType(t *testing.T) { 286 if h := HashForType("md5"); h == nil { 287 t.Fatalf("md5 hash is nil") 288 } else { 289 h.Write([]byte("foo")) 290 result := h.Sum(nil) 291 292 expected := "acbd18db4cc2f85cedef654fccc4a4d8" 293 actual := hex.EncodeToString(result) 294 if actual != expected { 295 t.Fatalf("bad hash: %s", actual) 296 } 297 } 298 299 if h := HashForType("sha1"); h == nil { 300 t.Fatalf("sha1 hash is nil") 301 } else { 302 h.Write([]byte("foo")) 303 result := h.Sum(nil) 304 305 expected := "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33" 306 actual := hex.EncodeToString(result) 307 if actual != expected { 308 t.Fatalf("bad hash: %s", actual) 309 } 310 } 311 312 if h := HashForType("sha256"); h == nil { 313 t.Fatalf("sha256 hash is nil") 314 } else { 315 h.Write([]byte("foo")) 316 result := h.Sum(nil) 317 318 expected := "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae" 319 actual := hex.EncodeToString(result) 320 if actual != expected { 321 t.Fatalf("bad hash: %s", actual) 322 } 323 } 324 325 if h := HashForType("sha512"); h == nil { 326 t.Fatalf("sha512 hash is nil") 327 } else { 328 h.Write([]byte("foo")) 329 result := h.Sum(nil) 330 331 expected := "f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc6638326e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7" 332 actual := hex.EncodeToString(result) 333 if actual != expected { 334 t.Fatalf("bad hash: %s", actual) 335 } 336 } 337 338 if HashForType("fake") != nil { 339 t.Fatalf("fake hash is not nil") 340 } 341 } 342 343 // TestDownloadFileUrl tests a special case where we use a local file for 344 // iso_url. In this case we can still verify the checksum but we should not 345 // delete the file if the checksum fails. Instead we'll just error and let the 346 // user fix the checksum. 347 func TestDownloadFileUrl(t *testing.T) { 348 cwd, err := os.Getwd() 349 if err != nil { 350 t.Fatalf("Unable to detect working directory: %s", err) 351 } 352 353 // source_path is a file path and source is a network path 354 sourcePath := fmt.Sprintf("%s/test-fixtures/fileurl/%s", cwd, "cake") 355 source := fmt.Sprintf("file://" + sourcePath) 356 t.Logf("Trying to download %s", source) 357 358 config := &DownloadConfig{ 359 Url: source, 360 // This should be wrong. We want to make sure we don't delete 361 Checksum: []byte("nope"), 362 Hash: HashForType("sha256"), 363 CopyFile: false, 364 } 365 366 client := NewDownloadClient(config) 367 368 // Verify that we fail to match the checksum 369 _, err = client.Get() 370 if err.Error() != "checksums didn't match expected: 6e6f7065" { 371 t.Fatalf("Unexpected failure; expected checksum not to match") 372 } 373 374 if _, err = os.Stat(sourcePath); err != nil { 375 t.Errorf("Could not stat source file: %s", sourcePath) 376 } 377 378 }