Skip to content

Commit

Permalink
chore(storage): enable more grpc integration tests (googleapis#6842)
Browse files Browse the repository at this point in the history
  • Loading branch information
BrennaEpp authored and kimihrr committed Oct 25, 2022
1 parent 4864309 commit d5ec0ea
Showing 1 changed file with 153 additions and 107 deletions.
260 changes: 153 additions & 107 deletions storage/integration_test.go
Expand Up @@ -61,6 +61,7 @@ import (
"google.golang.org/api/transport"
iampb "google.golang.org/genproto/googleapis/iam/v1"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)

type skipTransportTestKey string
Expand Down Expand Up @@ -3669,109 +3670,111 @@ func TestIntegration_PredefinedACLs(t *testing.T) {
}

func TestIntegration_ServiceAccount(t *testing.T) {
ctx := context.Background()
client := testConfig(ctx, t)
defer client.Close()

s, err := client.ServiceAccount(ctx, testutil.ProjID())
if err != nil {
t.Fatal(err)
}
want := "@gs-project-accounts.iam.gserviceaccount.com"
if !strings.Contains(s, want) {
t.Fatalf("got %v, want to contain %v", s, want)
}
multiTransportTest(context.Background(), t, func(t *testing.T, ctx context.Context, _, _ string, client *Client) {
s, err := client.ServiceAccount(ctx, testutil.ProjID())
if err != nil {
t.Fatal(err)
}
want := "@gs-project-accounts.iam.gserviceaccount.com"
if !strings.Contains(s, want) {
t.Fatalf("got %v, want to contain %v", s, want)
}
})
}

func TestIntegration_ReaderAttrs(t *testing.T) {
ctx := context.Background()
client := testConfig(ctx, t)
defer client.Close()
bkt := client.Bucket(bucketName)
multiTransportTest(context.Background(), t, func(t *testing.T, ctx context.Context, bucket, _ string, client *Client) {
bkt := client.Bucket(bucket)

const defaultType = "text/plain"
obj := "some-object"
c := randomContents()
if err := writeObject(ctx, bkt.Object(obj), defaultType, c); err != nil {
t.Errorf("Write for %v failed with %v", obj, err)
}
oh := bkt.Object(obj)
const defaultType = "text/plain"
o := bkt.Object("reader-attrs-obj")
c := randomContents()
if err := writeObject(ctx, o, defaultType, c); err != nil {
t.Errorf("Write for %v failed with %v", o.ObjectName(), err)
}
defer func() {
if err := o.Delete(ctx); err != nil {
log.Printf("failed to delete test object: %v", err)
}
}()

rc, err := oh.NewReader(ctx)
if err != nil {
t.Fatal(err)
}
rc, err := o.NewReader(ctx)
if err != nil {
t.Fatal(err)
}

attrs, err := oh.Attrs(ctx)
if err != nil {
t.Fatal(err)
}
attrs, err := o.Attrs(ctx)
if err != nil {
t.Fatal(err)
}

got := rc.Attrs
want := ReaderObjectAttrs{
Size: attrs.Size,
ContentType: attrs.ContentType,
ContentEncoding: attrs.ContentEncoding,
CacheControl: attrs.CacheControl,
LastModified: got.LastModified, // ignored, tested separately
Generation: attrs.Generation,
Metageneration: attrs.Metageneration,
}
if got != want {
t.Fatalf("got %v, wanted %v", got, want)
}
got := rc.Attrs
want := ReaderObjectAttrs{
Size: attrs.Size,
ContentType: attrs.ContentType,
ContentEncoding: attrs.ContentEncoding,
CacheControl: attrs.CacheControl,
LastModified: got.LastModified, // ignored, tested separately
Generation: attrs.Generation,
Metageneration: attrs.Metageneration,
}
if got != want {
t.Fatalf("got %v, wanted %v", got, want)
}

if got.LastModified.IsZero() {
t.Fatal("LastModified is 0, should be >0")
}
if got.LastModified.IsZero() {
t.Fatal("LastModified is 0, should be >0")
}
})
}

// Test that context cancellation correctly stops a download before completion.
func TestIntegration_ReaderCancel(t *testing.T) {
ctx := context.Background()
client := testConfig(ctx, t)
defer client.Close()
multiTransportTest(context.Background(), t, func(t *testing.T, ctx context.Context, bucket, _ string, client *Client) {
bkt := client.Bucket(bucket)
obj := bkt.Object("reader-cancel-obj")

bkt := client.Bucket(bucketName)
minObjectSize := 2500000 // 2.5 Mb

// Upload a 1MB object.
obj := bkt.Object("reader-cancel-obj")
w := obj.NewWriter(ctx)
c := randomContents()
for i := 0; i < 62500; i++ {
if _, err := w.Write(c); err != nil {
t.Fatalf("writer.Write: %v", err)
w := obj.NewWriter(ctx)
c := randomContents()
for written := 0; written < minObjectSize; {
n, err := w.Write(c)
if err != nil {
t.Fatalf("w.Write: %v", err)
}
written += n
}

}
w.Close()

// Create a reader (which makes a GET request to GCS and opens the body to
// read the object) and then cancel the context before reading.
readerCtx, cancel := context.WithCancel(ctx)
r, err := obj.NewReader(readerCtx)
if err != nil {
t.Fatalf("obj.NewReader: %v", err)
}
defer r.Close()
if err := w.Close(); err != nil {
t.Fatalf("writer close: %v", err)
}
defer func() {
if err := obj.Delete(ctx); err != nil {
log.Printf("failed to delete test object: %v", err)
}
}()

cancel()

// Read the object 1KB a time. We cannot guarantee that Reads will return a
// context canceled error immediately, but they should always do so before we
// reach EOF.
var readErr error
for i := 0; i < 1000; i++ {
buf := make([]byte, 1000)
_, readErr = r.Read(buf)
if readErr != nil {
if errors.Is(readErr, context.Canceled) {
return
// Create a reader (which makes a GET request to GCS and opens the body to
// read the object) and then cancel the context before reading.
readerCtx, cancel := context.WithCancel(ctx)
r, err := obj.NewReader(readerCtx)
if err != nil {
t.Fatalf("obj.NewReader: %v", err)
}
defer func() {
if err := r.Close(); err != nil {
log.Printf("r.Close(): %v", err)
}
break
}()

cancel()

_, err = io.Copy(io.Discard, r)
if err == nil || !errors.Is(err, context.Canceled) && !(status.Code(err) == codes.Canceled) {
t.Fatalf("r.Read: got error %v, want context.Canceled", err)
}
}
t.Fatalf("Reader.Read: got %v, want context.Canceled", readErr)
})
}

// Ensures that a file stored with a:
Expand Down Expand Up @@ -4026,34 +4029,77 @@ func TestIntegration_PostPolicyV4(t *testing.T) {

// Verify that custom scopes passed in by the user are applied correctly.
func TestIntegration_Scopes(t *testing.T) {
// A default client should be able to write objects since it has scope of
// FullControl
ctx := context.Background()
clientFullControl := testConfig(ctx, t)
defer clientFullControl.Close()
multiTransportTest(context.Background(), t, func(t *testing.T, ctx context.Context, bucket, _ string, client *Client) {
bkt := client.Bucket(bucket)
obj := bkt.Object("test-scopes")
contents := []byte("This object should not be written.\n")

bkt := clientFullControl.Bucket(bucketName)
obj := "FakeObj1"
contents := []byte("This object should be written successfully\n")
if err := writeObject(ctx, bkt.Object(obj), "text/plain", contents); err != nil {
t.Fatalf("writing: %v", err)
}
// A client with ReadOnly scope should be able to read bucket successfully.
if _, err := bkt.Attrs(ctx); err != nil {
t.Errorf("client with ScopeReadOnly was not able to read attrs: %v", err)
}

// A client with ReadOnly scope should not be able to write successfully.
clientReadOnly, err := NewClient(ctx, option.WithScopes(ScopeReadOnly))
defer clientReadOnly.Close()
if err != nil {
t.Fatalf("error creating client: %v", err)
}
// Should not be able to write successfully.
if err := writeObject(ctx, obj, "text/plain", contents); err == nil {
if err := obj.Delete(ctx); err != nil {
t.Logf("obj.Delete: %v", err)
}
t.Error("client with ScopeReadOnly was able to write an object unexpectedly.")
}

// Should not be able to change permissions.
if _, err := obj.Update(ctx, ObjectAttrsToUpdate{ACL: []ACLRule{{Entity: "domain-google.com", Role: RoleReader}}}); err == nil {
t.Error("client with ScopeReadWrite was able to change unexpectedly.")
}
}, option.WithScopes(ScopeReadOnly))

bkt = clientReadOnly.Bucket(bucketName)
obj = "FakeObj2"
contents = []byte("This object should not be written.\n")
multiTransportTest(context.Background(), t, func(t *testing.T, ctx context.Context, bucket, _ string, client *Client) {
bkt := client.Bucket(bucket)
obj := bkt.Object("test-scopes")
contents := []byte("This object should be written.\n")

if err := writeObject(ctx, bkt.Object(obj), "text/plain", contents); err == nil {
t.Fatal("client with ScopeReadOnly was able to write an object unexpectedly.")
}
// A client with ReadWrite scope should be able to read bucket successfully.
if _, err := bkt.Attrs(ctx); err != nil {
t.Errorf("client with ScopeReadOnly was not able to read attrs: %v", err)
}

// Should be able to write to an object.
if err := writeObject(ctx, obj, "text/plain", contents); err != nil {
t.Errorf("client with ScopeReadWrite was not able to write: %v", err)
}
defer func() {
if err := obj.Delete(ctx); err != nil {
t.Logf("obj.Delete: %v", err)
}
}()

// Should not be able to change permissions.
if _, err := obj.Update(ctx, ObjectAttrsToUpdate{ACL: []ACLRule{{Entity: "domain-google.com", Role: RoleReader}}}); err == nil {
t.Error("client with ScopeReadWrite was able to change permissions unexpectedly")
}
}, option.WithScopes(ScopeReadWrite))

multiTransportTest(context.Background(), t, func(t *testing.T, ctx context.Context, bucket, _ string, client *Client) {
bkt := client.Bucket(bucket)
obj := bkt.Object("test-scopes")
contents := []byte("This object should be written.\n")

// A client without any scopes should not be able to perform ops.
if _, err := bkt.Attrs(ctx); err == nil {
t.Errorf("client with no scopes was able to read attrs unexpectedly")
}

if err := writeObject(ctx, obj, "text/plain", contents); err == nil {
if err := obj.Delete(ctx); err != nil {
t.Logf("obj.Delete: %v", err)
}
t.Error("client with no scopes was able to write an object unexpectedly.")
}

if _, err := obj.Update(ctx, ObjectAttrsToUpdate{ACL: []ACLRule{{Entity: "domain-google.com", Role: RoleReader}}}); err == nil {
t.Error("client with no scopes was able to change permissions unexpectedly")
}
}, option.WithScopes(""))
}

func TestIntegration_SignedURL_Bucket(t *testing.T) {
Expand Down

0 comments on commit d5ec0ea

Please sign in to comment.