| OLD | NEW |
| 1 // Copyright 2015 The LUCI Authors. All rights reserved. | 1 // Copyright 2015 The LUCI Authors. All rights reserved. |
| 2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
| 3 // that can be found in the LICENSE file. | 3 // that can be found in the LICENSE file. |
| 4 | 4 |
| 5 package cipd | 5 package cipd |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "bytes" | 8 "bytes" |
| 9 "fmt" | 9 "fmt" |
| 10 "hash" | 10 "hash" |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 Input: []local.File{}, | 140 Input: []local.File{}, |
| 141 Output: &out, | 141 Output: &out, |
| 142 PackageName: "testing", | 142 PackageName: "testing", |
| 143 CompressionLevel: 5, | 143 CompressionLevel: 5, |
| 144 }) | 144 }) |
| 145 So(err, ShouldBeNil) | 145 So(err, ShouldBeNil) |
| 146 | 146 |
| 147 // Open it for reading. | 147 // Open it for reading. |
| 148 inst, err := local.OpenInstance(ctx, bytes.NewReader(out.Bytes()
), "", local.VerifyHash) | 148 inst, err := local.OpenInstance(ctx, bytes.NewReader(out.Bytes()
), "", local.VerifyHash) |
| 149 So(err, ShouldBeNil) | 149 So(err, ShouldBeNil) |
| 150 defer inst.Close() | |
| 151 | 150 |
| 152 Convey("RegisterInstance full flow", func(c C) { | 151 Convey("RegisterInstance full flow", func(c C) { |
| 153 client := mockClient(c, "", []expectedHTTPCall{ | 152 client := mockClient(c, "", []expectedHTTPCall{ |
| 154 { | 153 { |
| 155 Method: "POST", | 154 Method: "POST", |
| 156 Path: "/_ah/api/repo/v1/instance", | 155 Path: "/_ah/api/repo/v1/instance", |
| 157 Query: url.Values{ | 156 Query: url.Values{ |
| 158 "instance_id": []string{inst.Pi
n().InstanceID}, | 157 "instance_id": []string{inst.Pi
n().InstanceID}, |
| 159 "package_name": []string{inst.Pi
n().PackageName}, | 158 "package_name": []string{inst.Pi
n().PackageName}, |
| 160 }, | 159 }, |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 480 ctx := makeTestContext() | 479 ctx := makeTestContext() |
| 481 | 480 |
| 482 Convey("Mocking remote services", t, func(c C) { | 481 Convey("Mocking remote services", t, func(c C) { |
| 483 tempDir, err := ioutil.TempDir("", "cipd_test") | 482 tempDir, err := ioutil.TempDir("", "cipd_test") |
| 484 So(err, ShouldBeNil) | 483 So(err, ShouldBeNil) |
| 485 defer os.RemoveAll(tempDir) | 484 defer os.RemoveAll(tempDir) |
| 486 | 485 |
| 487 inst := buildInstanceInMemory(ctx, "testing/package", []local.Fi
le{ | 486 inst := buildInstanceInMemory(ctx, "testing/package", []local.Fi
le{ |
| 488 local.NewTestFile("file", "test data", false), | 487 local.NewTestFile("file", "test data", false), |
| 489 }) | 488 }) |
| 490 defer inst.Close() | |
| 491 | 489 |
| 492 client := mockClientForFetch(c, tempDir, []local.PackageInstance
{inst}) | 490 client := mockClientForFetch(c, tempDir, []local.PackageInstance
{inst}) |
| 493 | 491 |
| 494 Convey("FetchInstance (no cache)", func() { | 492 Convey("FetchInstance (no cache)", func() { |
| 495 reader, err := client.FetchInstance(ctx, inst.Pin()) | 493 reader, err := client.FetchInstance(ctx, inst.Pin()) |
| 496 So(err, ShouldBeNil) | 494 So(err, ShouldBeNil) |
| 495 defer reader.Close() // just in case |
| 497 | 496 |
| 498 // Backed by a temp file. | 497 // Backed by a temp file. |
| 499 tmpFile := reader.(deleteOnClose) | 498 tmpFile := reader.(deleteOnClose) |
| 500 _, err = os.Stat(tmpFile.Name()) | 499 _, err = os.Stat(tmpFile.Name()) |
| 501 So(err, ShouldBeNil) | 500 So(err, ShouldBeNil) |
| 502 | 501 |
| 503 fetched, err := local.OpenInstance(ctx, reader, "", loca
l.VerifyHash) | 502 fetched, err := local.OpenInstance(ctx, reader, "", loca
l.VerifyHash) |
| 504 So(err, ShouldBeNil) | 503 So(err, ShouldBeNil) |
| 505 So(fetched.Pin(), ShouldResemble, inst.Pin()) | 504 So(fetched.Pin(), ShouldResemble, inst.Pin()) |
| 506 » » » fetched.Close() // this closes the 'reader' too | 505 » » » tmpFile.Close() |
| 507 | 506 |
| 508 // The temp file is gone. | 507 // The temp file is gone. |
| 509 _, err = os.Stat(tmpFile.Name()) | 508 _, err = os.Stat(tmpFile.Name()) |
| 510 So(os.IsNotExist(err), ShouldBeTrue) | 509 So(os.IsNotExist(err), ShouldBeTrue) |
| 511 }) | 510 }) |
| 512 | 511 |
| 513 Convey("FetchInstance (with cache)", func() { | 512 Convey("FetchInstance (with cache)", func() { |
| 514 client.CacheDir = filepath.Join(tempDir, "instance_cache
") | 513 client.CacheDir = filepath.Join(tempDir, "instance_cache
") |
| 515 | 514 |
| 516 reader, err := client.FetchInstance(ctx, inst.Pin()) | 515 reader, err := client.FetchInstance(ctx, inst.Pin()) |
| 517 So(err, ShouldBeNil) | 516 So(err, ShouldBeNil) |
| 517 defer reader.Close() |
| 518 | 518 |
| 519 // Backed by a real file. | 519 // Backed by a real file. |
| 520 cachedFile := reader.(*os.File) | 520 cachedFile := reader.(*os.File) |
| 521 info1, err := os.Stat(cachedFile.Name()) | 521 info1, err := os.Stat(cachedFile.Name()) |
| 522 So(err, ShouldBeNil) | 522 So(err, ShouldBeNil) |
| 523 | 523 |
| 524 fetched, err := local.OpenInstance(ctx, reader, "", loca
l.VerifyHash) | 524 fetched, err := local.OpenInstance(ctx, reader, "", loca
l.VerifyHash) |
| 525 So(err, ShouldBeNil) | 525 So(err, ShouldBeNil) |
| 526 So(fetched.Pin(), ShouldResemble, inst.Pin()) | 526 So(fetched.Pin(), ShouldResemble, inst.Pin()) |
| 527 fetched.Close() // this closes the 'reader' too | |
| 528 | 527 |
| 529 // The real file is still there, in the cache. | 528 // The real file is still there, in the cache. |
| 530 _, err = os.Stat(cachedFile.Name()) | 529 _, err = os.Stat(cachedFile.Name()) |
| 531 So(err, ShouldBeNil) | 530 So(err, ShouldBeNil) |
| 532 | 531 |
| 533 // Fetch again. | 532 // Fetch again. |
| 534 reader, err = client.FetchInstance(ctx, inst.Pin()) | 533 reader, err = client.FetchInstance(ctx, inst.Pin()) |
| 535 So(err, ShouldBeNil) | 534 So(err, ShouldBeNil) |
| 536 | 535 |
| 537 // Got same exact file. | 536 // Got same exact file. |
| 538 cachedFile = reader.(*os.File) | 537 cachedFile = reader.(*os.File) |
| 539 info2, err := os.Stat(cachedFile.Name()) | 538 info2, err := os.Stat(cachedFile.Name()) |
| 540 So(err, ShouldBeNil) | 539 So(err, ShouldBeNil) |
| 541 So(os.SameFile(info1, info2), ShouldBeTrue) | 540 So(os.SameFile(info1, info2), ShouldBeTrue) |
| 542 | 541 |
| 543 reader.Close() | 542 reader.Close() |
| 544 }) | 543 }) |
| 545 | 544 |
| 546 Convey("FetchInstanceTo (no cache)", func() { | 545 Convey("FetchInstanceTo (no cache)", func() { |
| 547 tempFile := filepath.Join(tempDir, "pkg") | 546 tempFile := filepath.Join(tempDir, "pkg") |
| 548 out, err := os.OpenFile(tempFile, os.O_WRONLY|os.O_CREAT
E, 0666) | 547 out, err := os.OpenFile(tempFile, os.O_WRONLY|os.O_CREAT
E, 0666) |
| 549 So(err, ShouldBeNil) | 548 So(err, ShouldBeNil) |
| 550 defer out.Close() | 549 defer out.Close() |
| 551 | 550 |
| 552 err = client.FetchInstanceTo(ctx, inst.Pin(), out) | 551 err = client.FetchInstanceTo(ctx, inst.Pin(), out) |
| 553 So(err, ShouldBeNil) | 552 So(err, ShouldBeNil) |
| 554 out.Close() | 553 out.Close() |
| 555 | 554 |
| 556 » » » fetched, err := local.OpenInstanceFile(ctx, tempFile, ""
, local.VerifyHash) | 555 » » » fetched, closer, err := local.OpenInstanceFile(ctx, temp
File, "", local.VerifyHash) |
| 557 So(err, ShouldBeNil) | 556 So(err, ShouldBeNil) |
| 557 defer closer() |
| 558 So(fetched.Pin(), ShouldResemble, inst.Pin()) | 558 So(fetched.Pin(), ShouldResemble, inst.Pin()) |
| 559 fetched.Close() | |
| 560 }) | 559 }) |
| 561 | 560 |
| 562 Convey("FetchInstanceTo (with cache)", func() { | 561 Convey("FetchInstanceTo (with cache)", func() { |
| 563 client.CacheDir = filepath.Join(tempDir, "instance_cache
") | 562 client.CacheDir = filepath.Join(tempDir, "instance_cache
") |
| 564 | 563 |
| 565 tempFile := filepath.Join(tempDir, "pkg") | 564 tempFile := filepath.Join(tempDir, "pkg") |
| 566 out, err := os.OpenFile(tempFile, os.O_WRONLY|os.O_CREAT
E, 0666) | 565 out, err := os.OpenFile(tempFile, os.O_WRONLY|os.O_CREAT
E, 0666) |
| 567 So(err, ShouldBeNil) | 566 So(err, ShouldBeNil) |
| 568 defer out.Close() | 567 defer out.Close() |
| 569 | 568 |
| 570 err = client.FetchInstanceTo(ctx, inst.Pin(), out) | 569 err = client.FetchInstanceTo(ctx, inst.Pin(), out) |
| 571 So(err, ShouldBeNil) | 570 So(err, ShouldBeNil) |
| 572 out.Close() | 571 out.Close() |
| 573 | 572 |
| 574 » » » fetched, err := local.OpenInstanceFile(ctx, tempFile, ""
, local.VerifyHash) | 573 » » » fetched, closer, err := local.OpenInstanceFile(ctx, temp
File, "", local.VerifyHash) |
| 575 So(err, ShouldBeNil) | 574 So(err, ShouldBeNil) |
| 575 defer closer() |
| 576 So(fetched.Pin(), ShouldResemble, inst.Pin()) | 576 So(fetched.Pin(), ShouldResemble, inst.Pin()) |
| 577 fetched.Close() | |
| 578 }) | 577 }) |
| 579 | 578 |
| 580 Convey("FetchAndDeployInstance works", func() { | 579 Convey("FetchAndDeployInstance works", func() { |
| 581 // Install the package, fetching it from the fake server
. | 580 // Install the package, fetching it from the fake server
. |
| 582 err := client.FetchAndDeployInstance(ctx, "", inst.Pin()
) | 581 err := client.FetchAndDeployInstance(ctx, "", inst.Pin()
) |
| 583 So(err, ShouldBeNil) | 582 So(err, ShouldBeNil) |
| 584 | 583 |
| 585 // The file from the package should be installed. | 584 // The file from the package should be installed. |
| 586 data, err := ioutil.ReadFile(filepath.Join(tempDir, "fil
e")) | 585 data, err := ioutil.ReadFile(filepath.Join(tempDir, "fil
e")) |
| 587 So(err, ShouldBeNil) | 586 So(err, ShouldBeNil) |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 645 body, err := ioutil.ReadFile(filepath.Join(tempDir, relP
ath.(string))) | 644 body, err := ioutil.ReadFile(filepath.Join(tempDir, relP
ath.(string))) |
| 646 if ret := ShouldBeNil(err); ret != "" { | 645 if ret := ShouldBeNil(err); ret != "" { |
| 647 return ret | 646 return ret |
| 648 } | 647 } |
| 649 return ShouldEqual(string(body), data[0].(string)) | 648 return ShouldEqual(string(body), data[0].(string)) |
| 650 } | 649 } |
| 651 | 650 |
| 652 Convey("EnsurePackages full flow", func(c C) { | 651 Convey("EnsurePackages full flow", func(c C) { |
| 653 // Prepare a bunch of packages. | 652 // Prepare a bunch of packages. |
| 654 a1 := buildInstanceInMemory(ctx, "pkg/a", []local.File{l
ocal.NewTestFile("file a 1", "test data", false)}) | 653 a1 := buildInstanceInMemory(ctx, "pkg/a", []local.File{l
ocal.NewTestFile("file a 1", "test data", false)}) |
| 655 defer a1.Close() | |
| 656 a2 := buildInstanceInMemory(ctx, "pkg/a", []local.File{l
ocal.NewTestFile("file a 2", "test data", false)}) | 654 a2 := buildInstanceInMemory(ctx, "pkg/a", []local.File{l
ocal.NewTestFile("file a 2", "test data", false)}) |
| 657 defer a2.Close() | |
| 658 b := buildInstanceInMemory(ctx, "pkg/b", []local.File{lo
cal.NewTestFile("file b", "test data", false)}) | 655 b := buildInstanceInMemory(ctx, "pkg/b", []local.File{lo
cal.NewTestFile("file b", "test data", false)}) |
| 659 defer b.Close() | |
| 660 | 656 |
| 661 pil := func(insts ...local.PackageInstance) []local.Pack
ageInstance { | 657 pil := func(insts ...local.PackageInstance) []local.Pack
ageInstance { |
| 662 return insts | 658 return insts |
| 663 } | 659 } |
| 664 | 660 |
| 665 // Calls EnsurePackages, mocking fetch backend first. Ba
ckend will be mocked | 661 // Calls EnsurePackages, mocking fetch backend first. Ba
ckend will be mocked |
| 666 // to serve only 'fetched' packages. callEnsure will ens
ure the state | 662 // to serve only 'fetched' packages. callEnsure will ens
ure the state |
| 667 // reflected by the 'state' variable. | 663 // reflected by the 'state' variable. |
| 668 state := map[string][]local.PackageInstance{} | 664 state := map[string][]local.PackageInstance{} |
| 669 callEnsure := func(fetched ...local.PackageInstance) (Ac
tionMap, error) { | 665 callEnsure := func(fetched ...local.PackageInstance) (Ac
tionMap, error) { |
| (...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1015 w.Header().Add(k, s) | 1011 w.Header().Add(k, s) |
| 1016 } | 1012 } |
| 1017 } | 1013 } |
| 1018 w.WriteHeader(exp.Status) | 1014 w.WriteHeader(exp.Status) |
| 1019 } | 1015 } |
| 1020 if exp.Reply != "" { | 1016 if exp.Reply != "" { |
| 1021 w.Write([]byte(exp.Reply)) | 1017 w.Write([]byte(exp.Reply)) |
| 1022 } | 1018 } |
| 1023 s.index++ | 1019 s.index++ |
| 1024 } | 1020 } |
| OLD | NEW |