77
88 model_core "bonanza.build/pkg/model/core"
99 model_evaluation "bonanza.build/pkg/model/evaluation"
10+ model_core_pb "bonanza.build/pkg/proto/model/core"
1011 model_evaluation_cache_pb "bonanza.build/pkg/proto/model/evaluation/cache"
1112 "bonanza.build/pkg/storage/object"
1213
@@ -19,6 +20,7 @@ import (
1920 "google.golang.org/grpc/codes"
2021 "google.golang.org/grpc/status"
2122 "google.golang.org/protobuf/proto"
23+ "google.golang.org/protobuf/types/known/anypb"
2224 "google.golang.org/protobuf/types/known/emptypb"
2325 "google.golang.org/protobuf/types/known/wrapperspb"
2426
@@ -420,7 +422,7 @@ func TestRecursiveComputer(t *testing.T) {
420422 },
421423 ),
422424 ),
423- ).Return (model_core.Message [* model_evaluation_cache_pb.LookupResult , object.LocalReference ]{}, status .Error (codes .NotFound , "Tag does not exist" ))
425+ ).Return (model_core.Message [* model_evaluation_cache_pb.LookupResult , object.LocalReference ]{}, status .Error (codes .NotFound , "Object does not exist" ))
424426 computer .EXPECT ().ComputeMessageValue (gomock .Any (), gomock .Any (), gomock .Any ()).
425427 DoAndReturn (func (ctx context.Context , key model_core.Message [proto.Message , object.LocalReference ], e model_evaluation.Environment [object.LocalReference , model_core.ReferenceMetadata ]) (model_core.PatchedMessage [proto.Message , model_core.ReferenceMetadata ], error ) {
426428 return model_core.NewSimplePatchedMessage [model_core.ReferenceMetadata , proto.Message ](
@@ -443,4 +445,179 @@ func TestRecursiveComputer(t *testing.T) {
443445 Value : 42 ,
444446 }, value .Message )
445447 })
448+
449+ t .Run ("CacheLookupReturningUnexpectedResult" , func (t * testing.T ) {
450+ // The first cache lookup should typically contain an
451+ // Initial message, describing the initial set of
452+ // dependencies that need to be considered. If the
453+ // message is malformed and contains another type of
454+ // message, we should just ignore it.
455+ computer := NewMockComputerForTesting (ctrl )
456+ objectManager := NewMockObjectManagerForTesting (ctrl )
457+ tagResolver := NewMockBoundResolverForTesting (ctrl )
458+ cacheObjectReader := NewMockCacheObjectReaderForTesting (ctrl )
459+ cacheObjectReader .EXPECT ().GetDecodingParametersSizeBytes ().Return (16 ).AnyTimes ()
460+ cacheDeterministicEncoder := NewMockDeterministicBinaryEncoder (ctrl )
461+ cacheKeyedEncoder := NewMockKeyedBinaryEncoder (ctrl )
462+
463+ queuesFactory := model_evaluation.NewSimpleRecursiveComputerEvaluationQueuesFactory [object.LocalReference , model_core.ReferenceMetadata ](1 )
464+ queues := queuesFactory .NewQueues ()
465+ recursiveComputer := model_evaluation .NewRecursiveComputer (
466+ computer ,
467+ queues ,
468+ object .SHA256V1ReferenceFormat ,
469+ objectManager ,
470+ tagResolver ,
471+ /* actionTagKeyReference = */ object .MustNewSHA256V1LocalReference ("4466f601ba900ce4e0d606dc68dd0c35c5e976792784400514f42905d6deba6e" , 64722 , 0 , 0 , 0 ),
472+ cacheObjectReader ,
473+ cacheDeterministicEncoder ,
474+ cacheKeyedEncoder ,
475+ clock .SystemClock ,
476+ )
477+
478+ keyState , err := recursiveComputer .GetOrCreateKeyState (
479+ model_core.NewSimpleTopLevelMessage [object.LocalReference , proto.Message ](
480+ & wrapperspb.UInt32Value {
481+ Value : 12 ,
482+ },
483+ ),
484+ )
485+ require .NoError (t , err )
486+
487+ tagResolver .EXPECT ().ResolveTag (
488+ gomock .Any (),
489+ [... ]byte {
490+ 0x57 , 0x12 , 0x01 , 0xf0 , 0x80 , 0xf7 , 0xe1 , 0x9f ,
491+ 0x41 , 0x44 , 0x87 , 0x88 , 0x9b , 0xf3 , 0xc9 , 0x4f ,
492+ 0x61 , 0x68 , 0x71 , 0xd5 , 0x07 , 0x06 , 0x3e , 0x92 ,
493+ 0xdc , 0x40 , 0x42 , 0xbf , 0x2a , 0x3c , 0x01 , 0xec ,
494+ },
495+ ).Return (object .MustNewSHA256V1LocalReference ("829d56c5c910ff51bb09192f5655cd51c02e54c3e16b00d2fde8a6b7e3d814fc" , 95938 , 0 , 0 , 0 ), nil )
496+ cacheObjectReader .EXPECT ().ReadObject (
497+ gomock .Any (),
498+ util .Must (
499+ model_core .NewDecodable (
500+ object .MustNewSHA256V1LocalReference ("829d56c5c910ff51bb09192f5655cd51c02e54c3e16b00d2fde8a6b7e3d814fc" , 95938 , 0 , 0 , 0 ),
501+ []byte {
502+ 0x9c , 0x80 , 0x78 , 0x1a , 0xa4 , 0x29 , 0x20 , 0x6d ,
503+ 0x76 , 0xa4 , 0x4e , 0x8f , 0x4c , 0x2e , 0xce , 0xd5 ,
504+ },
505+ ),
506+ ),
507+ ).Return (model_core.NewSimpleMessage [object.LocalReference ](
508+ & model_evaluation_cache_pb.LookupResult {
509+ Result : & model_evaluation_cache_pb.LookupResult_MissingDependencies_ {
510+ MissingDependencies : & model_evaluation_cache_pb.LookupResult_MissingDependencies {},
511+ },
512+ },
513+ ), nil )
514+ computer .EXPECT ().ComputeMessageValue (gomock .Any (), gomock .Any (), gomock .Any ()).
515+ DoAndReturn (func (ctx context.Context , key model_core.Message [proto.Message , object.LocalReference ], e model_evaluation.Environment [object.LocalReference , model_core.ReferenceMetadata ]) (model_core.PatchedMessage [proto.Message , model_core.ReferenceMetadata ], error ) {
516+ return model_core.NewSimplePatchedMessage [model_core.ReferenceMetadata , proto.Message ](
517+ & wrapperspb.UInt64Value {Value : 13 },
518+ ), nil
519+ })
520+
521+ var value model_core.Message [proto.Message , object.LocalReference ]
522+ require .NoError (
523+ t ,
524+ program .RunLocal (ctx , func (ctx context.Context , siblingsGroup , dependenciesGroup program.Group ) error {
525+ queues .ProcessAllEvaluatableKeys (dependenciesGroup , recursiveComputer )
526+
527+ var err error
528+ value , err = recursiveComputer .WaitForMessageValue (ctx , keyState )
529+ return err
530+ }),
531+ )
532+ testutil .RequireEqualProto (t , & wrapperspb.UInt64Value {
533+ Value : 13 ,
534+ }, value .Message )
535+ })
536+
537+ t .Run ("CacheLookupWithoutDependencies" , func (t * testing.T ) {
538+ // In the extremely rare case that a key has no
539+ // dependencies, the initial lookup result may a value
540+ // directly. There should be no need to call into the
541+ // computer, as the cached value can be used.
542+ computer := NewMockComputerForTesting (ctrl )
543+ objectManager := NewMockObjectManagerForTesting (ctrl )
544+ tagResolver := NewMockBoundResolverForTesting (ctrl )
545+ cacheObjectReader := NewMockCacheObjectReaderForTesting (ctrl )
546+ cacheObjectReader .EXPECT ().GetDecodingParametersSizeBytes ().Return (16 ).AnyTimes ()
547+ cacheDeterministicEncoder := NewMockDeterministicBinaryEncoder (ctrl )
548+ cacheKeyedEncoder := NewMockKeyedBinaryEncoder (ctrl )
549+
550+ queuesFactory := model_evaluation.NewSimpleRecursiveComputerEvaluationQueuesFactory [object.LocalReference , model_core.ReferenceMetadata ](1 )
551+ queues := queuesFactory .NewQueues ()
552+ recursiveComputer := model_evaluation .NewRecursiveComputer (
553+ computer ,
554+ queues ,
555+ object .SHA256V1ReferenceFormat ,
556+ objectManager ,
557+ tagResolver ,
558+ /* actionTagKeyReference = */
559+ object .MustNewSHA256V1LocalReference ("2fbd13f1ee48876ec1e85961b59877c3916fb10ae23e7e1e45083feecafe1804" , 57483 , 0 , 0 , 0 ),
560+ cacheObjectReader ,
561+ cacheDeterministicEncoder ,
562+ cacheKeyedEncoder ,
563+ clock .SystemClock ,
564+ )
565+
566+ keyState , err := recursiveComputer .GetOrCreateKeyState (
567+ model_core.NewSimpleTopLevelMessage [object.LocalReference , proto.Message ](
568+ & wrapperspb.UInt32Value {
569+ Value : 24 ,
570+ },
571+ ),
572+ )
573+ require .NoError (t , err )
574+
575+ tagResolver .EXPECT ().ResolveTag (
576+ gomock .Any (),
577+ [... ]byte {
578+ 0x1e , 0x0f , 0x30 , 0xc1 , 0x1c , 0x0a , 0x4d , 0x1c ,
579+ 0xd6 , 0x18 , 0x13 , 0x8d , 0xa3 , 0x58 , 0x40 , 0xfa ,
580+ 0x31 , 0x22 , 0x07 , 0x66 , 0x38 , 0x45 , 0x22 , 0x9b ,
581+ 0x70 , 0x31 , 0xbb , 0xac , 0xe8 , 0x70 , 0x35 , 0x07 ,
582+ },
583+ ).Return (object .MustNewSHA256V1LocalReference ("e1749fb7b82448ae6941d4f7e515818efbf781e6fe2738465bd9ce876b8d9866" , 2345 , 0 , 0 , 0 ), nil )
584+ cacheObjectReader .EXPECT ().ReadObject (
585+ gomock .Any (),
586+ util .Must (
587+ model_core .NewDecodable (
588+ object .MustNewSHA256V1LocalReference ("e1749fb7b82448ae6941d4f7e515818efbf781e6fe2738465bd9ce876b8d9866" , 2345 , 0 , 0 , 0 ),
589+ []byte {
590+ 0xe5 , 0x83 , 0xfe , 0x6a , 0x73 , 0xa3 , 0x7f , 0xe9 ,
591+ 0x5c , 0xb8 , 0x4f , 0x3a , 0x54 , 0xdf , 0xd3 , 0x87 ,
592+ },
593+ ),
594+ ),
595+ ).Return (model_core.NewSimpleMessage [object.LocalReference ](
596+ & model_evaluation_cache_pb.LookupResult {
597+ Result : & model_evaluation_cache_pb.LookupResult_HitValue {
598+ HitValue : & model_core_pb.Any {
599+ Value : util .Must (anypb .New (& wrapperspb.UInt64Value {
600+ Value : 26 ,
601+ })),
602+ References : & model_core_pb.ReferenceSet {},
603+ },
604+ },
605+ },
606+ ), nil )
607+
608+ var value model_core.Message [proto.Message , object.LocalReference ]
609+ require .NoError (
610+ t ,
611+ program .RunLocal (ctx , func (ctx context.Context , siblingsGroup , dependenciesGroup program.Group ) error {
612+ queues .ProcessAllEvaluatableKeys (dependenciesGroup , recursiveComputer )
613+
614+ var err error
615+ value , err = recursiveComputer .WaitForMessageValue (ctx , keyState )
616+ return err
617+ }),
618+ )
619+ testutil .RequireEqualProto (t , & wrapperspb.UInt64Value {
620+ Value : 26 ,
621+ }, value .Message )
622+ })
446623}
0 commit comments