@@ -82,6 +82,52 @@ func TestMultiRetrieve(t *testing.T) {
8282 }
8383}
8484
85+ func TestRetrieveWithBadShaFails (t * testing.T ) {
86+ cc := startServer (t )
87+ defer cc .Close ()
88+
89+ ctx := grpcx .WriteWorkerID (context .Background (), "idA" )
90+ keys := []string {"foo" }
91+ st := "whatever"
92+ rt , artifacts := populate (ctx , cc , t , keys , 300 , st )
93+
94+ dst := makeTempDir (t )
95+ defer os .RemoveAll (dst )
96+
97+ client := jobpb .NewLegacyArtifactRetrievalServiceClient (cc )
98+ for _ , a := range artifacts {
99+ a .Sha256 = "badhash" // mutate hash
100+ if err := Retrieve (ctx , client , a , rt , dst ); err == nil {
101+ t .Errorf ("expected materialization to fail due to bad sha256 mismatch" )
102+ }
103+ }
104+ }
105+
106+ func TestRetrieveWithBadShaAndExperimentSucceeds (t * testing.T ) {
107+ cc := startServer (t )
108+ defer cc .Close ()
109+
110+ ctx := WithArtifactValidation (grpcx .WriteWorkerID (context .Background (), "idA" ), false )
111+ keys := []string {"foo" }
112+ st := "whatever"
113+ rt , artifacts := populate (ctx , cc , t , keys , 300 , st )
114+
115+ dst := makeTempDir (t )
116+ defer os .RemoveAll (dst )
117+
118+ client := jobpb .NewLegacyArtifactRetrievalServiceClient (cc )
119+ for _ , a := range artifacts {
120+ originalHash := a .Sha256
121+ a .Sha256 = "badhash" // mutate hash
122+ filename := makeFilename (dst , a .Name )
123+ if err := Retrieve (ctx , client , a , rt , dst ); err != nil {
124+ t .Errorf ("materialize failed but should have succeeded because validation was disabled via experiment: %v" , err )
125+ continue
126+ }
127+ verifySHA256 (t , filename , originalHash )
128+ }
129+ }
130+
85131// populate stages a set of artifacts with the given keys, each with
86132// slightly different sizes and chucksizes.
87133func populate (ctx context.Context , cc * grpc.ClientConn , t * testing.T , keys []string , size int , st string ) (string , []* jobpb.ArtifactMetadata ) {
@@ -266,6 +312,55 @@ func TestNewRetrieveWithResolution(t *testing.T) {
266312 checkStagedFiles (mds , dest , expected , t )
267313}
268314
315+ func TestIsArtifactValidationEnabled (t * testing.T ) {
316+ ctx := context .Background ()
317+ if ! isArtifactValidationEnabled (ctx ) {
318+ t .Errorf ("empty context should have validation enabled" )
319+ }
320+
321+ ctx2 := WithArtifactValidation (ctx , false )
322+ if isArtifactValidationEnabled (ctx2 ) {
323+ t .Errorf ("context with validation disabled should have validation disabled" )
324+ }
325+ }
326+
327+ func TestNewRetrieveWithBadShaFails (t * testing.T ) {
328+ expected := map [string ]string {"a.txt" : "a" }
329+ client := & fakeRetrievalService {artifacts : expected }
330+ dest := makeTempDir (t )
331+ defer os .RemoveAll (dest )
332+ ctx := grpcx .WriteWorkerID (context .Background (), "worker" )
333+
334+ _ , err := newMaterializeWithClient (ctx , client , client .fileArtifactsWithBadSha (), dest )
335+ if err == nil {
336+ t .Fatalf ("expected materialization to fail due to bad sha256 mismatch" )
337+ }
338+ }
339+
340+ func TestNewRetrieveWithBadShaAndExperimentSucceeds (t * testing.T ) {
341+ expected := map [string ]string {"a.txt" : "a" }
342+ client := & fakeRetrievalService {artifacts : expected }
343+ dest := makeTempDir (t )
344+ defer os .RemoveAll (dest )
345+
346+ ctx := WithArtifactValidation (grpcx .WriteWorkerID (context .Background (), "worker" ), false )
347+
348+ mds , err := newMaterializeWithClient (ctx , client , client .fileArtifactsWithBadSha (), dest )
349+ if err != nil {
350+ t .Fatalf ("materialize failed but should have succeeded because validation was disabled via experiment: %v" , err )
351+ }
352+
353+ generated := make (map [string ]string )
354+ for _ , md := range mds {
355+ name , _ := MustExtractFilePayload (md )
356+ payload , _ := proto .Marshal (& pipepb.ArtifactStagingToRolePayload {
357+ StagedName : name })
358+ generated [name ] = string (payload )
359+ }
360+
361+ checkStagedFiles (mds , dest , generated , t )
362+ }
363+
269364func checkStagedFiles (mds []* pipepb.ArtifactInformation , dest string , expected map [string ]string , t * testing.T ) {
270365 if len (mds ) != len (expected ) {
271366 t .Errorf ("wrong number of artifacts staged %v vs %v" , len (mds ), len (expected ))
@@ -323,6 +418,21 @@ func (fake *fakeRetrievalService) fileArtifactsWithoutStagingTo() []*pipepb.Arti
323418 return artifacts
324419}
325420
421+ func (fake * fakeRetrievalService ) fileArtifactsWithBadSha () []* pipepb.ArtifactInformation {
422+ var artifacts []* pipepb.ArtifactInformation
423+ for name := range fake .artifacts {
424+ payload , _ := proto .Marshal (& pipepb.ArtifactFilePayload {
425+ Path : filepath .Join ("/tmp" , name ),
426+ Sha256 : "badhash" ,
427+ })
428+ artifacts = append (artifacts , & pipepb.ArtifactInformation {
429+ TypeUrn : URNFileArtifact ,
430+ TypePayload : payload ,
431+ })
432+ }
433+ return artifacts
434+ }
435+
326436func (fake * fakeRetrievalService ) urlArtifactsWithoutStagingTo () []* pipepb.ArtifactInformation {
327437 var artifacts []* pipepb.ArtifactInformation
328438 for name := range fake .artifacts {
0 commit comments