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  }