@@ -3524,6 +3524,87 @@ func TestIntegration_WriterAppendTakeover(t *testing.T) {
3524
3524
})
3525
3525
}
3526
3526
3527
+ func TestIntegration_WriterAppendEdgeCases (t * testing.T ) {
3528
+ t .Skip ("b/402283880" )
3529
+ ctx := skipAllButBidi (context .Background (), "ZB test" )
3530
+ multiTransportTest (ctx , t , func (t * testing.T , ctx context.Context , _ , prefix string , client * Client ) {
3531
+ h := testHelper {t }
3532
+ bucketName := prefix + uidSpace .New ()
3533
+ bkt := client .Bucket (bucketName )
3534
+
3535
+ h .mustCreateZonalBucket (bkt , testutil .ProjID ())
3536
+ defer h .mustDeleteBucket (bkt )
3537
+
3538
+ objName := "object1"
3539
+ obj := bkt .Object (objName )
3540
+ defer h .mustDeleteObject (obj )
3541
+
3542
+ // Takeover Writer to a non-existent object should fail, with or
3543
+ // without generation specified.
3544
+ if _ , _ , err := obj .NewWriterFromAppendableObject (ctx , & AppendableWriterOpts {}); err == nil {
3545
+ t .Errorf ("NewWriterFromAppendableObject: got nil, want error" )
3546
+ }
3547
+ _ , _ , err := obj .Generation (1234 ).NewWriterFromAppendableObject (ctx , & AppendableWriterOpts {})
3548
+ if status .Code (err ) != codes .NotFound {
3549
+ t .Errorf ("NewWriterFromAppendableObject: got %v, want NotFound" , err )
3550
+ }
3551
+
3552
+ // If a takeover is opened, flush or close to the original writer
3553
+ // should fail.
3554
+ w := obj .NewWriter (ctx )
3555
+ w .Append = true
3556
+ w .ChunkSize = MiB
3557
+ if _ , err := w .Write (randomBytes3MiB ); err != nil {
3558
+ t .Fatalf ("w.Write: %v" , err )
3559
+ }
3560
+
3561
+ tw , _ , err := obj .Generation (w .Attrs ().Generation ).NewWriterFromAppendableObject (ctx , nil )
3562
+ if err != nil {
3563
+ t .Fatalf ("NewWriterFromAppendableObject: %v" , err )
3564
+ }
3565
+ if _ , err := tw .Write ([]byte ("hello world" )); err != nil {
3566
+ t .Fatalf ("tw.Write: %v" , err )
3567
+ }
3568
+ if _ , err := tw .Flush (); err != nil {
3569
+ t .Fatalf ("tw.Flush: %v" , err )
3570
+ }
3571
+
3572
+ // Expect precondition error when writer to orginal Writer.
3573
+ if _ , err := w .Write (randomBytes3MiB ); status .Code (err ) != codes .FailedPrecondition {
3574
+ t .Fatalf ("got %v" , err )
3575
+ }
3576
+
3577
+ // Another NewWriter to the unfinalized object should also return a
3578
+ // precondition error when data is flushed.
3579
+ w2 := obj .NewWriter (ctx )
3580
+ w2 .Append = true
3581
+ if _ , err := w2 .Write ([]byte ("hello world" )); err != nil {
3582
+ t .Fatalf ("w2.Write: %v" , err )
3583
+ }
3584
+ if _ , err := w2 .Flush (); status .Code (err ) != codes .FailedPrecondition {
3585
+ t .Fatalf ("w2.Flush: %v" , err )
3586
+ }
3587
+
3588
+ // If we add yet another takeover writer to finalize and delete the object,
3589
+ // tw should also return an error on flush.
3590
+ tw2 , _ , err := obj .Generation (w .Attrs ().Generation ).NewWriterFromAppendableObject (ctx , & AppendableWriterOpts {
3591
+ FinalizeOnClose : true ,
3592
+ })
3593
+ if err != nil {
3594
+ t .Fatalf ("NewWriterFromAppendableObject: %v" , err )
3595
+ }
3596
+ if err := tw2 .Close (); err != nil {
3597
+ t .Fatalf ("tw2.Close: %v" , err )
3598
+ }
3599
+ h .mustDeleteObject (obj )
3600
+ if _ , err := tw .Write ([]byte ("abcde" )); err != nil {
3601
+ t .Fatalf ("tw.Write: %v" , err )
3602
+ }
3603
+ if _ , err := tw .Flush (); status .Code (err ) != codes .FailedPrecondition {
3604
+ t .Errorf ("tw.Flush: got %v, want FailedPrecondition" , err )
3605
+ }
3606
+ })
3607
+ }
3527
3608
func TestIntegration_ZeroSizedObject (t * testing.T ) {
3528
3609
t .Parallel ()
3529
3610
multiTransportTest (context .Background (), t , func (t * testing.T , ctx context.Context , bucket , _ string , client * Client ) {
0 commit comments