go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/cipd/appengine/impl/repo/processing/bootstrap_test.go (about) 1 // Copyright 2021 The LUCI 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 processing 16 17 import ( 18 "bytes" 19 "context" 20 "io" 21 "testing" 22 23 api "go.chromium.org/luci/cipd/api/cipd/v1" 24 "go.chromium.org/luci/cipd/appengine/impl/testutil" 25 "go.chromium.org/luci/gae/impl/memory" 26 27 . "github.com/smartystreets/goconvey/convey" 28 . "go.chromium.org/luci/common/testing/assertions" 29 ) 30 31 func TestBootstrapPackageExtractor(t *testing.T) { 32 t.Parallel() 33 34 Convey("With mocks", t, func() { 35 var publishedRef *api.ObjectRef 36 37 ctx := memory.Use(context.Background()) 38 39 testInstance := instance(ctx, "some/pkg", api.HashAlgo_SHA256) 40 testBody := "12345678" 41 testBodyDigest := hexDigest(api.HashAlgo_SHA256, testBody) 42 43 cas := testutil.MockCAS{ 44 BeginUploadImpl: func(_ context.Context, r *api.BeginUploadRequest) (*api.UploadOperation, error) { 45 So(r.HashAlgo, ShouldEqual, api.HashAlgo_SHA256) 46 return &api.UploadOperation{ 47 OperationId: "op_id", 48 UploadUrl: "http://example.com/upload", 49 }, nil 50 }, 51 FinishUploadImpl: func(_ context.Context, r *api.FinishUploadRequest) (*api.UploadOperation, error) { 52 So(r.UploadOperationId, ShouldEqual, "op_id") 53 publishedRef = r.ForceHash 54 return &api.UploadOperation{Status: api.UploadStatus_PUBLISHED}, nil 55 }, 56 } 57 58 extracted := bytes.Buffer{} 59 60 ex := BootstrapPackageExtractor{ 61 CAS: &cas, 62 uploader: func(ctx context.Context, size int64, uploadURL string) io.Writer { return &extracted }, 63 } 64 65 Convey("Happy path", func() { 66 res, err := ex.Run(ctx, testInstance, packageReader(map[string]string{ 67 "some_binary.exe": testBody, 68 "some_binary.bat": "zzz", 69 ".cipdpkg/ignored": "zzz", 70 ".cipdpkg/also ignored": "zzz", 71 })) 72 So(err, ShouldBeNil) 73 So(res.Err, ShouldBeNil) 74 75 So(res.Result.(BootstrapExtractorResult), ShouldResemble, BootstrapExtractorResult{ 76 File: "some_binary.exe", 77 HashAlgo: "SHA256", 78 HashDigest: testBodyDigest, 79 Size: int64(len(testBody)), 80 }) 81 82 So(extracted.String(), ShouldEqual, testBody) 83 So(publishedRef, ShouldResembleProto, &api.ObjectRef{ 84 HashAlgo: api.HashAlgo_SHA256, 85 HexDigest: testBodyDigest, 86 }) 87 }) 88 89 Convey("Many files", func() { 90 res, err := ex.Run(ctx, testInstance, packageReader(map[string]string{ 91 "some_binary.exe": testBody, 92 "another_binary.exe": testBody, 93 })) 94 So(err, ShouldBeNil) 95 So(res.Err, ShouldErrLike, "contains multiple files") 96 }) 97 98 Convey("No files", func() { 99 res, err := ex.Run(ctx, testInstance, packageReader(map[string]string{ 100 ".cipdpkg/ignored": "zzz", 101 ".cipdpkg/also ignored": "zzz", 102 })) 103 So(err, ShouldBeNil) 104 So(res.Err, ShouldErrLike, "contains no files") 105 }) 106 107 Convey("Not at root", func() { 108 res, err := ex.Run(ctx, testInstance, packageReader(map[string]string{ 109 "dir/some_binary.exe": testBody, 110 })) 111 So(err, ShouldBeNil) 112 So(res.Err, ShouldErrLike, "not at the package root") 113 }) 114 }) 115 }