@@ -629,3 +629,82 @@ func TestMirrorTarget_AddEntries_NoPendingCheckpoint(t *testing.T) {
629629 t .Errorf ("got error %v, want ErrNoPendingCheckpoint" , err )
630630 }
631631}
632+
633+ func TestMirrorTarget_AddEntries_UploadStartConflicts (t * testing.T ) {
634+ const (
635+ testIntegratedSize = uint64 (3072 )
636+ testUploadEnd = uint64 (4096 )
637+ )
638+
639+ ctx := t .Context ()
640+ testPendingCPCustom := mustSignCP (testPendingCPOrigin , testUploadEnd , testPendingCPRoot , testLogSigner )
641+
642+ for _ , tc := range []struct {
643+ name string
644+ uploadStart uint64
645+ wantConflict bool
646+ }{
647+ {
648+ name : "exact start" ,
649+ uploadStart : testIntegratedSize ,
650+ wantConflict : false ,
651+ },
652+ {
653+ name : "re-upload within limit" ,
654+ uploadStart : testIntegratedSize - maxExcessEntries ,
655+ wantConflict : false ,
656+ },
657+ {
658+ name : "re-upload too far back" ,
659+ uploadStart : testIntegratedSize - maxExcessEntries - 1 ,
660+ wantConflict : true ,
661+ },
662+ {
663+ name : "uploadStart > nextEntry" ,
664+ uploadStart : testIntegratedSize + 256 ,
665+ wantConflict : true ,
666+ },
667+ } {
668+ t .Run (tc .name , func (t * testing.T ) {
669+ mt := & MirrorTarget {
670+ logVerifier : testLogVerifier ,
671+ signer : testMirrorSigner ,
672+ writer : & fakeMirrorWriter {
673+ integrateFunc : func (ctx context.Context , fromBundleIdx uint64 , bundles iter.Seq2 [* api.EntryBundle , error ]) (uint64 , []byte , error ) {
674+ for _ , err := range bundles {
675+ if err != nil {
676+ return 0 , nil , err
677+ }
678+ }
679+ pendingCPRoot , err := base64 .StdEncoding .DecodeString (testPendingCPRoot )
680+ return testUploadEnd , pendingCPRoot , err
681+ },
682+ updateCheckpointFunc : func (ctx context.Context , f func (oldCP []byte ) (newCP []byte , err error )) error {
683+ return nil
684+ },
685+ },
686+ reader : & fakeLogReader {
687+ sizeFunc : func (ctx context.Context ) (uint64 , error ) { return testIntegratedSize , nil },
688+ },
689+ cpSource : func (ctx context.Context ) ([]byte , error ) { return []byte (testPendingCPCustom ), nil },
690+ }
691+
692+ validTicket , err := mt .seal ([]byte (testPendingCPCustom ))
693+ if err != nil {
694+ t .Fatalf ("seal failed: %v" , err )
695+ }
696+
697+ _ , _ , _ , _ , err = mt .AddEntries (ctx , tc .uploadStart , testUploadEnd , validTicket , func () (* MirrorPackage , error ) {
698+ return nil , io .EOF
699+ })
700+
701+ if gotConflict := errors .Is (err , ErrConflict ); gotConflict != tc .wantConflict {
702+ t .Fatalf ("AddEntries got conflict %v, want conflict %v (err: %v)" , gotConflict , tc .wantConflict , err )
703+ }
704+ if ! tc .wantConflict && err != nil {
705+ t .Fatalf ("AddEntries unexpected error: %v" , err )
706+ }
707+
708+ })
709+ }
710+ }
0 commit comments