From a40676cb751c0241a70a7e13f8244a3287b950dd Mon Sep 17 00:00:00 2001 From: Chris Cotter Date: Fri, 4 Dec 2020 01:45:36 -0500 Subject: [PATCH 01/25] test(storage): add retry conformance tests [WIP] --- storage/conformance_test.go | 105 ++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/storage/conformance_test.go b/storage/conformance_test.go index bf26c9515ae..0f1c2237fc0 100644 --- a/storage/conformance_test.go +++ b/storage/conformance_test.go @@ -16,10 +16,13 @@ package storage import ( "bytes" + "context" "encoding/base64" "encoding/json" "fmt" "io/ioutil" + "log" + "net/http" "net/url" "strconv" "strings" @@ -29,8 +32,110 @@ import ( storage_v1_tests "cloud.google.com/go/storage/internal/test/conformance" "github.com/golang/protobuf/jsonpb" "github.com/google/go-cmp/cmp" + "google.golang.org/api/option" + raw "google.golang.org/api/storage/v1" + htransport "google.golang.org/api/transport/http" ) +func TestRetryConformance(t *testing.T) { + // Create test cases. + cases := []struct{ + instruction string // add later + method func(ctx context.Context, c *Client) error + expectSuccess bool + }{ + { + instruction: "return-503-after-256K", + method: func(ctx context.Context, c *Client) error { + + + _, err := c.Bucket("cjcotter-devrel-test").Object("file.txt").Attrs(ctx) + return err + }, + expectSuccess: true, + }, + { + instruction: "reset-connection", + method: func(ctx context.Context, c *Client) error { + _, err := c.Bucket("cjcotter-devrel-test").Object("file.txt").Attrs(ctx) + return err + }, + expectSuccess: false, + }, + } + + ctx := context.Background() + + // Create custom client that sends instruction + base := http.DefaultTransport + trans, err := htransport.NewTransport(ctx, base, option.WithScopes(raw.DevstorageFullControlScope), + option.WithUserAgent("custom-user-agent")) + if err != nil { + // Handle error. + } + c := http.Client{Transport:trans} + + // Add RoundTripper to the created HTTP client. + instr := "reset-connection" + wrappedTrans := &withInstruction{rt: c.Transport, instr: instr} + c.Transport = *wrappedTrans + + // Supply this client to storage.NewClient + client, err := NewClient(ctx, option.WithHTTPClient(&c), option.WithEndpoint("http://localhost:9000/storage/v1/")) + if err != nil { + // Handle error. + } + + // Setup bucket and object + bktName := "cjcotter-devrel-test" + if err := client.Bucket(bktName).Create(ctx,"myproj", &BucketAttrs{}); err != nil { + t.Errorf("Error creating bucket: %v", err) + } + + w := client.Bucket(bktName).Object("file.txt").NewWriter(ctx) + if _, err := w.Write([]byte("abcdef")); err != nil { + t.Errorf("Error writing object to emulator: %v", err) + } + if err := w.Close(); err != nil { + t.Errorf("Error writing object to emulator in Close: %v", err) + } + + + + for _, c := range cases { + // Transport manipulation is not thread safe. + retries = 2 + wrappedTrans.instr = c.instruction + err := c.method(ctx, client) + if err == nil && !c.expectSuccess { + t.Errorf("case: want failure, got success") + } + if err != nil && c.expectSuccess { + t.Errorf("case: want success, got %v", err) + } + } +} + +var retries int + +type withInstruction struct { + rt http.RoundTripper + instr string +} + +func (wi withInstruction) RoundTrip(r *http.Request) (*http.Response, error) { + if retries > 0 { + r.Header.Set("x-goog-testbench-instructions", wi.instr) + retries -= 1 + } + log.Printf("Request: %+v\nRetries: %v\n\n", r, retries) + resp, err := wi.rt.RoundTrip(r) + //if err != nil{ + // log.Printf("Error: %+v", err) + //} + return resp, err +} + func TestPostPolicyV4Conformance(t *testing.T) { oldUTCNow := utcNow defer func() { From f606eeb4c3195533bc75e129fad4f52b60016a18 Mon Sep 17 00:00:00 2001 From: Chris Cotter Date: Mon, 8 Mar 2021 15:20:54 -0500 Subject: [PATCH 02/25] [WIP] test(storage): add retry conformance tests --- storage/conformance_test.go | 170 ++++++++++++++++++++++-------------- 1 file changed, 105 insertions(+), 65 deletions(-) diff --git a/storage/conformance_test.go b/storage/conformance_test.go index 0f1c2237fc0..3045bda6406 100644 --- a/storage/conformance_test.go +++ b/storage/conformance_test.go @@ -20,10 +20,12 @@ import ( "encoding/base64" "encoding/json" "fmt" + "io" "io/ioutil" "log" "net/http" "net/url" + "os" "strconv" "strings" "testing" @@ -37,98 +39,115 @@ import ( htransport "google.golang.org/api/transport/http" ) +type retryFunc func(ctx context.Context, c *Client) error + +type retryCase struct { + // Instruction header to send to the emulator. + instruction string + // Functions that will wrap the library method to call. + methods []retryFunc + // If true, the call should succeed after a retry. + expectSuccess bool +} + func TestRetryConformance(t *testing.T) { - // Create test cases. - cases := []struct{ - instruction string // add later - method func(ctx context.Context, c *Client) error - expectSuccess bool - }{ - { - instruction: "return-503-after-256K", - method: func(ctx context.Context, c *Client) error { + if os.Getenv("STORAGE_EMULATOR_HOST") == "" { + t.Skip("This test must use the testbench emulator; set STORAGE_EMULATOR_HOST to run.") + } - _, err := c.Bucket("cjcotter-devrel-test").Object("file.txt").Attrs(ctx) + bucketName := "cjcotter-devrel-test" + objName := "file.txt" + + // List of methods to retry. This is pretty much impossible to encode in a + // schema because they vary a lot across libraries. + // I'd want to flesh this out with two lists of functions: + // 1. A list of idempotent calls (should give expectSuccess = True for + // retryable errors, false for other errors). + // 2. A list of non-idempotent calls (should give expectSuccess = False for + // everything). + funcs := []retryFunc{ + func(ctx context.Context, c *Client) error { + _, err := c.Bucket(bucketName).Object(objName).Attrs(ctx) + return err + }, + func(ctx context.Context, c *Client) error { + r, err := c.Bucket(bucketName).Object(objName).NewReader(ctx) + if err != nil { return err - }, + } + _, err = io.Copy(ioutil.Discard, r) + return err + }, + } + // Create test cases. + // TODO: add unmarshaling from conf test JSON + cases := []retryCase{ + { + instruction: "return-503-after-256K", + methods: funcs, expectSuccess: true, }, { - instruction: "reset-connection", - method: func(ctx context.Context, c *Client) error { - _, err := c.Bucket("cjcotter-devrel-test").Object("file.txt").Attrs(ctx) - return err - }, + instruction: "reset-connection", + methods: funcs, expectSuccess: false, }, } ctx := context.Background() - // Create custom client that sends instruction - base := http.DefaultTransport - trans, err := htransport.NewTransport(ctx, base, option.WithScopes(raw.DevstorageFullControlScope), - option.WithUserAgent("custom-user-agent")) - if err != nil { - // Handle error. - } - c := http.Client{Transport:trans} - - // Add RoundTripper to the created HTTP client. - instr := "reset-connection" - wrappedTrans := &withInstruction{rt: c.Transport, instr: instr} - c.Transport = *wrappedTrans - - // Supply this client to storage.NewClient - client, err := NewClient(ctx, option.WithHTTPClient(&c), option.WithEndpoint("http://localhost:9000/storage/v1/")) + // Create non-wrapped client to use for setup steps. + client, err := NewClient(ctx) if err != nil { - // Handle error. - } - - // Setup bucket and object - bktName := "cjcotter-devrel-test" - if err := client.Bucket(bktName).Create(ctx,"myproj", &BucketAttrs{}); err != nil { - t.Errorf("Error creating bucket: %v", err) - } - - w := client.Bucket(bktName).Object("file.txt").NewWriter(ctx) - if _, err := w.Write([]byte("abcdef")); err != nil { - t.Errorf("Error writing object to emulator: %v", err) - } - if err := w.Close(); err != nil { - t.Errorf("Error writing object to emulator in Close: %v", err) + t.Fatalf("storage.NewClient: %v", err) } + for _, c := range cases { + for i, m := range c.methods { + testName := fmt.Sprintf("%v - %v", c.instruction, i) + t.Run(testName, func(t *testing.T) { + // Setup bucket and object + if err := client.Bucket(bucketName).Create(ctx, "myproj", &BucketAttrs{}); err != nil { + t.Errorf("Error creating bucket: %v", err) + } + w := client.Bucket(bucketName).Object(objName).NewWriter(ctx) + if _, err := w.Write([]byte("abcdef")); err != nil { + t.Errorf("Error writing object to emulator: %v", err) + } + if err := w.Close(); err != nil { + t.Errorf("Error writing object to emulator in Close: %v", err) + } - for _, c := range cases { - // Transport manipulation is not thread safe. - retries = 2 - wrappedTrans.instr = c.instruction - err := c.method(ctx, client) - if err == nil && !c.expectSuccess { - t.Errorf("case: want failure, got success") - } - if err != nil && c.expectSuccess { - t.Errorf("case: want success, got %v", err) + wrapped, err := wrappedClient(c) + if err != nil { + t.Errorf("error creating wrapped client: %v", err) + } + err = m(ctx, wrapped) + if c.expectSuccess && err != nil { + t.Errorf("want success, got %v", err) + } + if !c.expectSuccess && err == nil { + t.Errorf("want failure, got success") + } + }) } } } -var retries int - type withInstruction struct { - rt http.RoundTripper - instr string + rt http.RoundTripper + instr string + retries int } -func (wi withInstruction) RoundTrip(r *http.Request) (*http.Response, error) { - if retries > 0 { +func (wi *withInstruction) RoundTrip(r *http.Request) (*http.Response, error) { + if wi.retries > 0 { r.Header.Set("x-goog-testbench-instructions", wi.instr) - retries -= 1 + wi.retries -= 1 } - log.Printf("Request: %+v\nRetries: %v\n\n", r, retries) + log.Printf("Request: %+v\nRetries: %v\n\n", r, wi.retries) resp, err := wi.rt.RoundTrip(r) //if err != nil{ // log.Printf("Error: %+v", err) @@ -136,6 +155,27 @@ func (wi withInstruction) RoundTrip(r *http.Request) (*http.Response, error) { return resp, err } +// Create custom client that sends instruction +func wrappedClient(r retryCase) (*Client, error) { + ctx := context.Background() + base := http.DefaultTransport + trans, err := htransport.NewTransport(ctx, base, option.WithScopes(raw.DevstorageFullControlScope), + option.WithUserAgent("custom-user-agent")) + if err != nil { + return nil, fmt.Errorf("failed to create http client: %v", err) + } + c := http.Client{Transport: trans} + + // Add RoundTripper to the created HTTP client. + instr := r.instruction + wrappedTrans := &withInstruction{rt: c.Transport, instr: instr, retries: 2} + c.Transport = wrappedTrans + + // Supply this client to storage.NewClient + client, err := NewClient(ctx, option.WithHTTPClient(&c), option.WithEndpoint("http://localhost:9000/storage/v1/")) + return client, err +} + func TestPostPolicyV4Conformance(t *testing.T) { oldUTCNow := utcNow defer func() { From aa6115539bdc691660aefec71449c163546dc0f3 Mon Sep 17 00:00:00 2001 From: Chris Cotter Date: Thu, 11 Mar 2021 16:13:06 -0500 Subject: [PATCH 03/25] separate idempotent/non-idempotent calls --- storage/conformance_test.go | 121 ++++++++++++++++++++++++------------ 1 file changed, 82 insertions(+), 39 deletions(-) diff --git a/storage/conformance_test.go b/storage/conformance_test.go index 3045bda6406..af2e2d494af 100644 --- a/storage/conformance_test.go +++ b/storage/conformance_test.go @@ -50,51 +50,93 @@ type retryCase struct { expectSuccess bool } +var objName = "file.txt" + +// List of methods to retry. This is pretty much impossible to encode in a +// schema because they vary a lot across libraries. +// I'd want to flesh this out with two lists of functions: +// 1. A list of idempotent calls (should give expectSuccess = True for +// retryable errors, false for other errors). +// 2. A list of non-idempotent calls (should give expectSuccess = False for +// everything). +var idempotentOps = []retryFunc{ + // storage.objects.get + func(ctx context.Context, c *Client) error { + _, err := c.Bucket(bucketName).Object(objName).Attrs(ctx) + return err + }, + // GET object (XML API) + func(ctx context.Context, c *Client) error { + r, err := c.Bucket(bucketName).Object(objName).NewReader(ctx) + if err != nil { + return err + } + _, err = io.Copy(ioutil.Discard, r) + return err + }, + // storage.objects.update (preconditions) + func(ctx context.Context, c *Client) error { + uattrs := ObjectAttrsToUpdate{Metadata: map[string]string{"foo": "bar"}} + conds := Conditions{MetagenerationMatch: 10} + _, err := c.Bucket(bucketName).Object(objName).If(conds).Update(ctx, uattrs) + return err + }, + // storage.buckets.update (preconditions) + func(ctx context.Context, c *Client) error { + uattrs := BucketAttrsToUpdate{StorageClass: "ARCHIVE"} + conds := BucketConditions{MetagenerationMatch: 10} + _, err := c.Bucket(bucketName).If(conds).Update(ctx, uattrs) + return err + }, +} + +var nonIdempotentOps = []retryFunc{ + // storage.objects.update (no preconditions) + func(ctx context.Context, c *Client) error { + uattrs := ObjectAttrsToUpdate{Metadata: map[string]string{"foo": "bar"}} + _, err := c.Bucket(bucketName).Object(objName).Update(ctx, uattrs) + return err + }, + // storage.buckets.update (no preconditions) + func(ctx context.Context, c *Client) error { + uattrs := BucketAttrsToUpdate{StorageClass: "ARCHIVE"} + _, err := c.Bucket(bucketName).Update(ctx, uattrs) + return err + }, +} + + +// Create test cases. +// TODO: add unmarshaling from conf test JSON +var cases = []retryCase{ + { + instruction: "return-400", + methods: idempotentOps, + expectSuccess: false, + }, + { + instruction: "return-400", + methods: nonIdempotentOps, + expectSuccess: false, + }, + { + instruction: "reset-connection", + methods: idempotentOps, + expectSuccess: true, + }, + { + instruction: "reset-connection", + methods: nonIdempotentOps, + expectSuccess: true, + }, +} + func TestRetryConformance(t *testing.T) { if os.Getenv("STORAGE_EMULATOR_HOST") == "" { t.Skip("This test must use the testbench emulator; set STORAGE_EMULATOR_HOST to run.") } - bucketName := "cjcotter-devrel-test" - objName := "file.txt" - - // List of methods to retry. This is pretty much impossible to encode in a - // schema because they vary a lot across libraries. - // I'd want to flesh this out with two lists of functions: - // 1. A list of idempotent calls (should give expectSuccess = True for - // retryable errors, false for other errors). - // 2. A list of non-idempotent calls (should give expectSuccess = False for - // everything). - funcs := []retryFunc{ - func(ctx context.Context, c *Client) error { - _, err := c.Bucket(bucketName).Object(objName).Attrs(ctx) - return err - }, - func(ctx context.Context, c *Client) error { - r, err := c.Bucket(bucketName).Object(objName).NewReader(ctx) - if err != nil { - return err - } - _, err = io.Copy(ioutil.Discard, r) - return err - }, - } - // Create test cases. - // TODO: add unmarshaling from conf test JSON - cases := []retryCase{ - { - instruction: "return-503-after-256K", - methods: funcs, - expectSuccess: true, - }, - { - instruction: "reset-connection", - methods: funcs, - expectSuccess: false, - }, - } - ctx := context.Background() // Create non-wrapped client to use for setup steps. @@ -120,6 +162,7 @@ func TestRetryConformance(t *testing.T) { t.Errorf("Error writing object to emulator in Close: %v", err) } + // Create wrapped client which will send emulator instructions. wrapped, err := wrappedClient(c) if err != nil { t.Errorf("error creating wrapped client: %v", err) From 400a64baf8950b58f88896a3d69a9500db9815ab Mon Sep 17 00:00:00 2001 From: Chris Cotter Date: Thu, 25 Mar 2021 13:55:31 -0400 Subject: [PATCH 04/25] rework schema --- storage/conformance_test.go | 198 +++++++---------- .../test/conformance/retry_tests.json | 25 +++ storage/internal/test/conformance/test.pb.go | 204 ++++++++++++------ storage/internal/test/conformance/test.proto | 10 + 4 files changed, 262 insertions(+), 175 deletions(-) create mode 100644 storage/internal/test/conformance/retry_tests.json diff --git a/storage/conformance_test.go b/storage/conformance_test.go index af2e2d494af..822816b503d 100644 --- a/storage/conformance_test.go +++ b/storage/conformance_test.go @@ -39,96 +39,51 @@ import ( htransport "google.golang.org/api/transport/http" ) -type retryFunc func(ctx context.Context, c *Client) error - -type retryCase struct { - // Instruction header to send to the emulator. - instruction string - // Functions that will wrap the library method to call. - methods []retryFunc - // If true, the call should succeed after a retry. - expectSuccess bool -} +type retryFunc func(ctx context.Context, c *Client, preconditions bool) error var objName = "file.txt" -// List of methods to retry. This is pretty much impossible to encode in a -// schema because they vary a lot across libraries. -// I'd want to flesh this out with two lists of functions: -// 1. A list of idempotent calls (should give expectSuccess = True for -// retryable errors, false for other errors). -// 2. A list of non-idempotent calls (should give expectSuccess = False for -// everything). -var idempotentOps = []retryFunc{ - // storage.objects.get - func(ctx context.Context, c *Client) error { - _, err := c.Bucket(bucketName).Object(objName).Attrs(ctx) - return err - }, - // GET object (XML API) - func(ctx context.Context, c *Client) error { - r, err := c.Bucket(bucketName).Object(objName).NewReader(ctx) - if err != nil { +// Methods to retry. This is a map whose keys are a string describing a standard +// API call (e.g. storage.objects.get) and values are a list of functions which +// wrap library methods that implement these calls. There may be multiple values +// because multiple library methods may use the same call (e.g. get could be a +// read or just a metadata get). +var methods = map[string][]retryFunc{ + "storage.objects.get": { + func(ctx context.Context, c *Client, _ bool) error { + _, err := c.Bucket(bucketName).Object(objName).Attrs(ctx) return err - } - _, err = io.Copy(ioutil.Discard, r) - return err - }, - // storage.objects.update (preconditions) - func(ctx context.Context, c *Client) error { - uattrs := ObjectAttrsToUpdate{Metadata: map[string]string{"foo": "bar"}} - conds := Conditions{MetagenerationMatch: 10} - _, err := c.Bucket(bucketName).Object(objName).If(conds).Update(ctx, uattrs) - return err - }, - // storage.buckets.update (preconditions) - func(ctx context.Context, c *Client) error { - uattrs := BucketAttrsToUpdate{StorageClass: "ARCHIVE"} - conds := BucketConditions{MetagenerationMatch: 10} - _, err := c.Bucket(bucketName).If(conds).Update(ctx, uattrs) - return err - }, -} - -var nonIdempotentOps = []retryFunc{ - // storage.objects.update (no preconditions) - func(ctx context.Context, c *Client) error { - uattrs := ObjectAttrsToUpdate{Metadata: map[string]string{"foo": "bar"}} - _, err := c.Bucket(bucketName).Object(objName).Update(ctx, uattrs) - return err - }, - // storage.buckets.update (no preconditions) - func(ctx context.Context, c *Client) error { - uattrs := BucketAttrsToUpdate{StorageClass: "ARCHIVE"} - _, err := c.Bucket(bucketName).Update(ctx, uattrs) - return err - }, -} - - -// Create test cases. -// TODO: add unmarshaling from conf test JSON -var cases = []retryCase{ - { - instruction: "return-400", - methods: idempotentOps, - expectSuccess: false, - }, - { - instruction: "return-400", - methods: nonIdempotentOps, - expectSuccess: false, - }, - { - instruction: "reset-connection", - methods: idempotentOps, - expectSuccess: true, + }, + func(ctx context.Context, c *Client, _ bool) error { + r, err := c.Bucket(bucketName).Object(objName).NewReader(ctx) + if err != nil { + return err + } + _, err = io.Copy(ioutil.Discard, r) + return err + }, }, - { - instruction: "reset-connection", - methods: nonIdempotentOps, - expectSuccess: true, + "storage.objects.update": { + func(ctx context.Context, c *Client, preconditions bool) error { + uattrs := ObjectAttrsToUpdate{Metadata: map[string]string{"foo": "bar"}} + obj := c.Bucket(bucketName).Object(objName) + if preconditions { + obj = obj.If(Conditions{MetagenerationMatch: 10}) + } + _, err := obj.Update(ctx, uattrs) + return err + }, }, + "storage.buckets.update": { + func(ctx context.Context, c *Client, preconditions bool) error { + uattrs := BucketAttrsToUpdate{StorageClass: "ARCHIVE"} + bkt := c.Bucket(bucketName) + if preconditions { + bkt = bkt.If(BucketConditions{MetagenerationMatch: 10}) + } + _, err := bkt.Update(ctx, uattrs) + return err + }}, } func TestRetryConformance(t *testing.T) { @@ -145,38 +100,51 @@ func TestRetryConformance(t *testing.T) { t.Fatalf("storage.NewClient: %v", err) } - for _, c := range cases { - for i, m := range c.methods { - testName := fmt.Sprintf("%v - %v", c.instruction, i) - t.Run(testName, func(t *testing.T) { - // Setup bucket and object - if err := client.Bucket(bucketName).Create(ctx, "myproj", &BucketAttrs{}); err != nil { - t.Errorf("Error creating bucket: %v", err) - } - - w := client.Bucket(bucketName).Object(objName).NewWriter(ctx) - if _, err := w.Write([]byte("abcdef")); err != nil { - t.Errorf("Error writing object to emulator: %v", err) - } - if err := w.Close(); err != nil { - t.Errorf("Error writing object to emulator in Close: %v", err) - } - - // Create wrapped client which will send emulator instructions. - wrapped, err := wrappedClient(c) - if err != nil { - t.Errorf("error creating wrapped client: %v", err) - } - err = m(ctx, wrapped) - if c.expectSuccess && err != nil { - t.Errorf("want success, got %v", err) + _, _, testFiles := parseFiles(t) + for _, testFile := range(testFiles) { + for _, tc := range(testFile.RetryTests) { + for _, i := range(tc.Instructions) { + for _, m := range(tc.Methods) { + testName := fmt.Sprintf("%v - %v - %v", tc.Description, i, m) + t.Run(testName, func(t *testing.T) { + // Setup bucket and object + // TODO: customize this by operation. + if err := client.Bucket(bucketName).Create(ctx, "myproj", &BucketAttrs{}); err != nil { + t.Errorf("Error creating bucket: %v", err) + } + + w := client.Bucket(bucketName).Object(objName).NewWriter(ctx) + if _, err := w.Write([]byte("abcdef")); err != nil { + t.Errorf("Error writing object to emulator: %v", err) + } + if err := w.Close(); err != nil { + t.Errorf("Error writing object to emulator in Close: %v", err) + } + + // Create wrapped client which will send emulator instructions. + wrapped, err := wrappedClient(i) + if err != nil { + t.Errorf("error creating wrapped client: %v", err) + } + if len(methods[m]) == 0 { + t.Logf("No tests for operation %v", m) + } + for _, f := range(methods[m]) { + err = f(ctx, wrapped, tc.PreconditionProvided) + if tc.ExpectSuccess && err != nil { + t.Errorf("want success, got %v", err) + } + if !tc.ExpectSuccess && err == nil { + t.Errorf("want failure, got success") + } + } + + }) } - if !c.expectSuccess && err == nil { - t.Errorf("want failure, got success") - } - }) + } } } + } type withInstruction struct { @@ -199,7 +167,7 @@ func (wi *withInstruction) RoundTrip(r *http.Request) (*http.Response, error) { } // Create custom client that sends instruction -func wrappedClient(r retryCase) (*Client, error) { +func wrappedClient(instruction string) (*Client, error) { ctx := context.Background() base := http.DefaultTransport trans, err := htransport.NewTransport(ctx, base, option.WithScopes(raw.DevstorageFullControlScope), @@ -210,7 +178,7 @@ func wrappedClient(r retryCase) (*Client, error) { c := http.Client{Transport: trans} // Add RoundTripper to the created HTTP client. - instr := r.instruction + instr := instruction wrappedTrans := &withInstruction{rt: c.Transport, instr: instr, retries: 2} c.Transport = wrappedTrans diff --git a/storage/internal/test/conformance/retry_tests.json b/storage/internal/test/conformance/retry_tests.json new file mode 100644 index 00000000000..fae7862dd4e --- /dev/null +++ b/storage/internal/test/conformance/retry_tests.json @@ -0,0 +1,25 @@ +{ + "retryTests": [ + { + "description": "always idempotent, retryable errors", + "instructions": ["return-503", "reset-connection"], + "methods": ["storage.objects.get", "storage.buckets.get"], + "preconditionProvided": false, + "expectSuccess": true + }, + { + "description": "always idempotent, retryable errors", + "instructions": ["return-503", "reset-connection"], + "methods": ["storage.objects.get", "storage.buckets.get"], + "preconditionProvided": true, + "expectSuccess": true + }, + { + "description": "always idempotent, non-retryable errors", + "instructions": ["return-400", "return-401"], + "methods": ["storage.objects.get", "storage.buckets.get"], + "preconditionProvided": false, + "expectSuccess": false + } + ] +} \ No newline at end of file diff --git a/storage/internal/test/conformance/test.pb.go b/storage/internal/test/conformance/test.pb.go index df7d64e4c94..a99356c2d8e 100644 --- a/storage/internal/test/conformance/test.pb.go +++ b/storage/internal/test/conformance/test.pb.go @@ -5,10 +5,9 @@ package google_cloud_conformance_storage_v1 import ( fmt "fmt" - math "math" - proto "github.com/golang/protobuf/proto" timestamp "github.com/golang/protobuf/ptypes/timestamp" + math "math" ) // Reference imports to suppress errors if they are not otherwise used. @@ -53,6 +52,7 @@ func (UrlStyle) EnumDescriptor() ([]byte, []int) { type TestFile struct { SigningV4Tests []*SigningV4Test `protobuf:"bytes,1,rep,name=signing_v4_tests,json=signingV4Tests,proto3" json:"signing_v4_tests,omitempty"` PostPolicyV4Tests []*PostPolicyV4Test `protobuf:"bytes,2,rep,name=post_policy_v4_tests,json=postPolicyV4Tests,proto3" json:"post_policy_v4_tests,omitempty"` + RetryTests []*RetryTest `protobuf:"bytes,3,rep,name=retry_tests,json=retryTests,proto3" json:"retry_tests,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -97,6 +97,13 @@ func (m *TestFile) GetPostPolicyV4Tests() []*PostPolicyV4Test { return nil } +func (m *TestFile) GetRetryTests() []*RetryTest { + if m != nil { + return m.RetryTests + } + return nil +} + type SigningV4Test struct { FileName string `protobuf:"bytes,1,opt,name=fileName,proto3" json:"fileName,omitempty"` Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` @@ -547,6 +554,77 @@ func (m *PostPolicyV4Test) GetPolicyOutput() *PolicyOutput { return nil } +type RetryTest struct { + Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` + Instructions []string `protobuf:"bytes,2,rep,name=instructions,proto3" json:"instructions,omitempty"` + Methods []string `protobuf:"bytes,3,rep,name=methods,proto3" json:"methods,omitempty"` + PreconditionProvided bool `protobuf:"varint,4,opt,name=preconditionProvided,proto3" json:"preconditionProvided,omitempty"` + ExpectSuccess bool `protobuf:"varint,5,opt,name=expectSuccess,proto3" json:"expectSuccess,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *RetryTest) Reset() { *m = RetryTest{} } +func (m *RetryTest) String() string { return proto.CompactTextString(m) } +func (*RetryTest) ProtoMessage() {} +func (*RetryTest) Descriptor() ([]byte, []int) { + return fileDescriptor_c161fcfdc0c3ff1e, []int{7} +} + +func (m *RetryTest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_RetryTest.Unmarshal(m, b) +} +func (m *RetryTest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_RetryTest.Marshal(b, m, deterministic) +} +func (m *RetryTest) XXX_Merge(src proto.Message) { + xxx_messageInfo_RetryTest.Merge(m, src) +} +func (m *RetryTest) XXX_Size() int { + return xxx_messageInfo_RetryTest.Size(m) +} +func (m *RetryTest) XXX_DiscardUnknown() { + xxx_messageInfo_RetryTest.DiscardUnknown(m) +} + +var xxx_messageInfo_RetryTest proto.InternalMessageInfo + +func (m *RetryTest) GetDescription() string { + if m != nil { + return m.Description + } + return "" +} + +func (m *RetryTest) GetInstructions() []string { + if m != nil { + return m.Instructions + } + return nil +} + +func (m *RetryTest) GetMethods() []string { + if m != nil { + return m.Methods + } + return nil +} + +func (m *RetryTest) GetPreconditionProvided() bool { + if m != nil { + return m.PreconditionProvided + } + return false +} + +func (m *RetryTest) GetExpectSuccess() bool { + if m != nil { + return m.ExpectSuccess + } + return false +} + func init() { proto.RegisterEnum("google.cloud.conformance.storage.v1.UrlStyle", UrlStyle_name, UrlStyle_value) proto.RegisterType((*TestFile)(nil), "google.cloud.conformance.storage.v1.TestFile") @@ -560,67 +638,73 @@ func init() { proto.RegisterType((*PolicyOutput)(nil), "google.cloud.conformance.storage.v1.PolicyOutput") proto.RegisterMapType((map[string]string)(nil), "google.cloud.conformance.storage.v1.PolicyOutput.FieldsEntry") proto.RegisterType((*PostPolicyV4Test)(nil), "google.cloud.conformance.storage.v1.PostPolicyV4Test") + proto.RegisterType((*RetryTest)(nil), "google.cloud.conformance.storage.v1.RetryTest") } func init() { proto.RegisterFile("test.proto", fileDescriptor_c161fcfdc0c3ff1e) } var fileDescriptor_c161fcfdc0c3ff1e = []byte{ - // 901 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xef, 0x6e, 0xe2, 0x46, - 0x10, 0xaf, 0x21, 0x70, 0x30, 0xe4, 0x72, 0x74, 0xcb, 0x55, 0x2e, 0x1f, 0x5a, 0x44, 0x3f, 0x94, - 0x56, 0xaa, 0xef, 0x42, 0x73, 0xd2, 0x35, 0x6a, 0x55, 0x05, 0xc2, 0x5d, 0xa2, 0xe6, 0x12, 0x6a, - 0x4c, 0x4e, 0x27, 0x55, 0x42, 0xc6, 0x1e, 0xc0, 0x3d, 0xe3, 0x75, 0xbc, 0xeb, 0xe8, 0x78, 0x8f, - 0x3e, 0x45, 0x9f, 0xa6, 0x6f, 0xd0, 0x4f, 0x95, 0xfa, 0x18, 0xd5, 0xee, 0xda, 0x60, 0x2e, 0x44, - 0x82, 0xfe, 0xf9, 0xc6, 0xcc, 0xec, 0xfc, 0x7e, 0xeb, 0x99, 0xdf, 0xcc, 0x02, 0xc0, 0x91, 0x71, - 0x23, 0x8c, 0x28, 0xa7, 0xe4, 0xf3, 0x29, 0xa5, 0x53, 0x1f, 0x0d, 0xc7, 0xa7, 0xb1, 0x6b, 0x38, - 0x34, 0x98, 0xd0, 0x68, 0x6e, 0x07, 0x0e, 0x1a, 0x8c, 0xd3, 0xc8, 0x9e, 0xa2, 0x71, 0x7b, 0x58, - 0xff, 0x4c, 0x1d, 0x7a, 0x22, 0x53, 0xc6, 0xf1, 0xe4, 0x09, 0xf7, 0xe6, 0xc8, 0xb8, 0x3d, 0x0f, - 0x15, 0x4a, 0xf3, 0x77, 0x0d, 0x4a, 0x16, 0x32, 0xfe, 0xc2, 0xf3, 0x91, 0xfc, 0x0c, 0x55, 0xe6, - 0x4d, 0x03, 0x2f, 0x98, 0x8e, 0x6e, 0x8f, 0x46, 0x82, 0x8b, 0xe9, 0x5a, 0x23, 0xdf, 0xaa, 0xb4, - 0xdb, 0xc6, 0x16, 0x6c, 0xc6, 0x40, 0x25, 0x5f, 0x1f, 0x09, 0x44, 0xf3, 0x80, 0x65, 0x4d, 0x46, - 0x26, 0x50, 0x0b, 0x29, 0xe3, 0xa3, 0x90, 0xfa, 0x9e, 0xb3, 0x58, 0x31, 0xe4, 0x24, 0xc3, 0xb3, - 0xad, 0x18, 0xfa, 0x94, 0xf1, 0xbe, 0xcc, 0x4f, 0x48, 0x3e, 0x0c, 0xdf, 0xf3, 0xb0, 0xe6, 0x9f, - 0x45, 0x78, 0xb8, 0x76, 0x13, 0x52, 0x87, 0xd2, 0xc4, 0xf3, 0xf1, 0xd2, 0x9e, 0xa3, 0xae, 0x35, - 0xb4, 0x56, 0xd9, 0x5c, 0xda, 0xa4, 0x01, 0x15, 0x17, 0x99, 0x13, 0x79, 0x21, 0xf7, 0x68, 0xa0, - 0xe7, 0x64, 0x38, 0xeb, 0x22, 0x1f, 0x43, 0x71, 0x1c, 0x3b, 0x6f, 0x91, 0xeb, 0x79, 0x19, 0x4c, - 0x2c, 0xe1, 0xa7, 0xe3, 0x5f, 0xd0, 0xe1, 0xfa, 0x9e, 0xf2, 0x2b, 0x4b, 0xf8, 0xe7, 0xc8, 0x67, - 0xd4, 0xd5, 0x0b, 0xca, 0xaf, 0x2c, 0xf2, 0x29, 0x00, 0xbe, 0x0b, 0xbd, 0xc8, 0x96, 0x44, 0xc5, - 0x86, 0xd6, 0xca, 0x9b, 0x19, 0x0f, 0x79, 0x0e, 0xe5, 0x65, 0x77, 0xf4, 0x07, 0x0d, 0xad, 0x55, - 0x69, 0xd7, 0xd3, 0xa2, 0xa4, 0xfd, 0x33, 0xac, 0xf4, 0x84, 0xb9, 0x3a, 0x2c, 0xbe, 0x01, 0xdf, - 0x85, 0xe8, 0x70, 0x74, 0x87, 0x91, 0xaf, 0x97, 0xd4, 0x37, 0x64, 0x5c, 0xe4, 0x0d, 0x3c, 0x98, - 0xa1, 0xed, 0x62, 0xc4, 0xf4, 0xb2, 0x2c, 0xf7, 0x0f, 0xbb, 0x37, 0xd4, 0x38, 0x53, 0x08, 0xbd, - 0x80, 0x47, 0x0b, 0x33, 0xc5, 0x23, 0x11, 0x54, 0x6f, 0x62, 0x8c, 0x16, 0xa3, 0xd0, 0x8e, 0xec, - 0x39, 0x72, 0xc1, 0x01, 0x92, 0xe3, 0xe5, 0x3f, 0xe0, 0xf8, 0x49, 0x40, 0xf5, 0x97, 0x48, 0x8a, - 0xeb, 0xd1, 0xcd, 0xba, 0x57, 0x94, 0x98, 0x39, 0x33, 0x9c, 0xa3, 0x5e, 0x51, 0x25, 0x56, 0x16, - 0x39, 0x87, 0x52, 0x1c, 0xf9, 0x03, 0xbe, 0xf0, 0x51, 0xdf, 0x6f, 0x68, 0xad, 0x83, 0xf6, 0xd7, - 0x5b, 0xdd, 0x61, 0x98, 0x24, 0x99, 0xcb, 0x74, 0xf2, 0x14, 0x3e, 0x52, 0x7d, 0xee, 0xd0, 0x38, - 0x70, 0xcf, 0x28, 0xe3, 0x81, 0x90, 0xcf, 0x43, 0xc9, 0xb7, 0x29, 0x44, 0x8e, 0x41, 0x4f, 0x4b, - 0xde, 0xb5, 0x03, 0x1a, 0x78, 0x8e, 0xed, 0x9b, 0x78, 0x13, 0x23, 0xe3, 0xfa, 0x81, 0x4c, 0xbb, - 0x37, 0x4e, 0xda, 0x50, 0x4b, 0x63, 0x03, 0x1e, 0x79, 0xc1, 0xd4, 0xa2, 0xa2, 0x2e, 0xfa, 0x23, - 0x99, 0xb7, 0x31, 0x56, 0x3f, 0x86, 0xfd, 0x6c, 0x47, 0x48, 0x15, 0xf2, 0x6f, 0x71, 0x91, 0x08, - 0x5c, 0xfc, 0x24, 0x35, 0x28, 0xdc, 0xda, 0x7e, 0x8c, 0x89, 0xaa, 0x95, 0x71, 0x9c, 0x7b, 0xae, - 0xd5, 0x3b, 0x50, 0xdb, 0x54, 0xe9, 0x5d, 0x30, 0x9a, 0x47, 0x40, 0xba, 0x34, 0x70, 0x3d, 0x21, - 0x5e, 0xdb, 0x7f, 0x65, 0x73, 0x67, 0x86, 0x2c, 0x51, 0x79, 0x84, 0x8c, 0x09, 0x95, 0x8b, 0xed, - 0x51, 0x36, 0x33, 0x9e, 0xe6, 0x18, 0xaa, 0x6a, 0x5c, 0x97, 0xb9, 0x8c, 0x18, 0x40, 0x1c, 0x1a, - 0x70, 0x0c, 0xf8, 0x05, 0x06, 0x53, 0x3e, 0x33, 0xed, 0x60, 0x8a, 0x32, 0xb7, 0x60, 0x6e, 0x88, - 0x08, 0x0e, 0xc6, 0xed, 0x88, 0xb3, 0xd7, 0x1e, 0x9f, 0xc9, 0xfd, 0x51, 0x36, 0x33, 0x9e, 0xe6, - 0xaf, 0x7b, 0x50, 0x51, 0x24, 0xe7, 0x41, 0x18, 0xf3, 0x8c, 0x5c, 0xb4, 0x7b, 0xe5, 0x92, 0xfb, - 0x5f, 0xe4, 0x92, 0xbf, 0x5f, 0x2e, 0xab, 0xb5, 0xb2, 0x77, 0xcf, 0x5a, 0x29, 0xac, 0xad, 0x95, - 0xbb, 0xeb, 0xa3, 0xf0, 0x1f, 0xad, 0x0f, 0x0b, 0x8a, 0x13, 0x0f, 0x7d, 0x97, 0xe9, 0x25, 0x39, - 0xb7, 0xdf, 0x6d, 0xb9, 0x8a, 0x97, 0x05, 0x36, 0x5e, 0xc8, 0x74, 0x35, 0xac, 0x09, 0x16, 0x19, - 0x02, 0x38, 0xcb, 0x16, 0xeb, 0x65, 0x79, 0xa1, 0x67, 0x3b, 0x20, 0xaf, 0xf4, 0x61, 0x66, 0x80, - 0xea, 0xdf, 0x42, 0x25, 0xc3, 0xb6, 0x93, 0x60, 0xff, 0xd2, 0x60, 0x5f, 0x61, 0x5f, 0xc5, 0x5c, - 0xe8, 0xa2, 0x0a, 0xf9, 0x38, 0xf2, 0xd3, 0xe4, 0x38, 0xf2, 0xc9, 0x70, 0x59, 0x0a, 0xf5, 0x2a, - 0x7d, 0xbf, 0xc3, 0x85, 0x15, 0xe8, 0xc6, 0x5a, 0x1c, 0xc1, 0xe3, 0x74, 0x84, 0x4f, 0xd1, 0xa1, - 0x2e, 0xba, 0x2a, 0x25, 0xd1, 0xc7, 0xe6, 0xe0, 0xbf, 0xf9, 0xd4, 0x3f, 0x34, 0x31, 0x66, 0xeb, - 0x2f, 0xe3, 0xfb, 0x4f, 0x9d, 0x76, 0xf7, 0xa9, 0x33, 0xa1, 0x12, 0xae, 0xda, 0x2a, 0x61, 0x2b, - 0xed, 0xa7, 0xbb, 0xca, 0xc1, 0xcc, 0x82, 0x90, 0x21, 0xec, 0x87, 0x99, 0xfa, 0xc8, 0x4f, 0xae, - 0xb4, 0x0f, 0x77, 0x2e, 0xac, 0xb9, 0x06, 0xf3, 0xd5, 0x15, 0x94, 0xd2, 0x31, 0x24, 0x07, 0x00, - 0xfd, 0x13, 0xeb, 0x6c, 0x34, 0xb0, 0xde, 0x5c, 0xf4, 0xaa, 0x1f, 0x10, 0x1d, 0x6a, 0xd7, 0xe7, - 0xa6, 0x35, 0x3c, 0xb9, 0x18, 0x9d, 0x5d, 0x0d, 0xac, 0xde, 0x69, 0x12, 0xd1, 0xc8, 0x27, 0xf0, - 0xb8, 0x33, 0xec, 0xfe, 0xd8, 0xb3, 0x46, 0x9d, 0xab, 0xe1, 0xe5, 0xa9, 0x0c, 0x5f, 0x9e, 0xbc, - 0xea, 0x55, 0x73, 0x9d, 0xd7, 0xf0, 0x85, 0x43, 0xe7, 0xdb, 0x5c, 0xab, 0xaf, 0xfd, 0x96, 0xfb, - 0xf2, 0xa5, 0x3a, 0xd7, 0x95, 0xe7, 0x06, 0x49, 0xec, 0xfa, 0xd0, 0x90, 0xff, 0x41, 0x8c, 0xee, - 0x2a, 0x71, 0x5c, 0x94, 0xd3, 0xf7, 0xcd, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xa3, 0x35, 0x7d, - 0xfd, 0xbd, 0x09, 0x00, 0x00, + // 992 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xdd, 0x6e, 0xe3, 0x44, + 0x14, 0xc6, 0x49, 0x7f, 0x92, 0xe3, 0xb6, 0x1b, 0x86, 0x2e, 0x32, 0xb9, 0x80, 0x28, 0x20, 0x51, + 0x90, 0xf0, 0x6e, 0x43, 0x57, 0x5a, 0x2a, 0x10, 0xea, 0xdf, 0x6e, 0x2b, 0xba, 0x6d, 0x98, 0x24, + 0x5d, 0xad, 0x84, 0x14, 0x39, 0xf6, 0x49, 0x62, 0xd6, 0xf1, 0xb8, 0x33, 0xe3, 0x6a, 0xf3, 0x1e, + 0xbc, 0x00, 0xb7, 0xbc, 0x07, 0xcf, 0xc1, 0x15, 0x12, 0x8f, 0x81, 0x3c, 0x63, 0x3b, 0xce, 0x6e, + 0x2a, 0x25, 0xfc, 0xdc, 0xe5, 0x9c, 0x33, 0xdf, 0xf7, 0x79, 0xce, 0x7c, 0x73, 0x26, 0x00, 0x12, + 0x85, 0xb4, 0x23, 0xce, 0x24, 0x23, 0x9f, 0x8e, 0x18, 0x1b, 0x05, 0x68, 0xbb, 0x01, 0x8b, 0x3d, + 0xdb, 0x65, 0xe1, 0x90, 0xf1, 0x89, 0x13, 0xba, 0x68, 0x0b, 0xc9, 0xb8, 0x33, 0x42, 0xfb, 0x6e, + 0xbf, 0xfe, 0x89, 0x5e, 0xf4, 0x48, 0x41, 0x06, 0xf1, 0xf0, 0x91, 0xf4, 0x27, 0x28, 0xa4, 0x33, + 0x89, 0x34, 0x4b, 0xf3, 0xd7, 0x12, 0x54, 0xba, 0x28, 0xe4, 0x33, 0x3f, 0x40, 0xf2, 0x13, 0xd4, + 0x84, 0x3f, 0x0a, 0xfd, 0x70, 0xd4, 0xbf, 0x3b, 0xe8, 0x27, 0x5a, 0xc2, 0x32, 0x1a, 0xe5, 0x3d, + 0xb3, 0xd5, 0xb2, 0x97, 0x50, 0xb3, 0x3b, 0x1a, 0x7c, 0x73, 0x90, 0x30, 0xd2, 0x1d, 0x51, 0x0c, + 0x05, 0x19, 0xc2, 0x6e, 0xc4, 0x84, 0xec, 0x47, 0x2c, 0xf0, 0xdd, 0xe9, 0x4c, 0xa1, 0xa4, 0x14, + 0x9e, 0x2c, 0xa5, 0xd0, 0x66, 0x42, 0xb6, 0x15, 0x3e, 0x15, 0x79, 0x3f, 0x7a, 0x2b, 0x23, 0xc8, + 0x35, 0x98, 0x1c, 0x25, 0x9f, 0xa6, 0xf4, 0x65, 0x45, 0x6f, 0x2f, 0x45, 0x4f, 0x13, 0x9c, 0xe2, + 0x05, 0x9e, 0xfd, 0x14, 0xcd, 0x3f, 0x37, 0x60, 0x7b, 0x6e, 0x6b, 0xa4, 0x0e, 0x95, 0xa1, 0x1f, + 0xe0, 0x95, 0x33, 0x41, 0xcb, 0x68, 0x18, 0x7b, 0x55, 0x9a, 0xc7, 0xa4, 0x01, 0xa6, 0x87, 0xc2, + 0xe5, 0x7e, 0x24, 0x7d, 0x16, 0x5a, 0x25, 0x55, 0x2e, 0xa6, 0xc8, 0x87, 0xb0, 0x31, 0x88, 0xdd, + 0xd7, 0x28, 0xad, 0xb2, 0x2a, 0xa6, 0x51, 0x92, 0x67, 0x83, 0x9f, 0xd1, 0x95, 0xd6, 0x9a, 0xce, + 0xeb, 0x28, 0xc9, 0x4f, 0x50, 0x8e, 0x99, 0x67, 0xad, 0xeb, 0xbc, 0x8e, 0xc8, 0xc7, 0x00, 0xf8, + 0x26, 0xf2, 0xb9, 0xa3, 0x84, 0x36, 0x1a, 0xc6, 0x5e, 0x99, 0x16, 0x32, 0xe4, 0x29, 0x54, 0xf3, + 0xe3, 0xb6, 0x36, 0x1b, 0xc6, 0x9e, 0xd9, 0xaa, 0x67, 0x6d, 0xc8, 0x0c, 0x61, 0x77, 0xb3, 0x15, + 0x74, 0xb6, 0x38, 0xd9, 0x03, 0xbe, 0x89, 0xd0, 0x95, 0xe8, 0xf5, 0x78, 0x60, 0x55, 0xf4, 0x1e, + 0x0a, 0x29, 0xf2, 0x0a, 0x36, 0xc7, 0xe8, 0x78, 0xc8, 0x85, 0x55, 0x55, 0x0d, 0xfe, 0x7e, 0x75, + 0x87, 0xd8, 0xe7, 0x9a, 0xe1, 0x2c, 0x94, 0x7c, 0x4a, 0x33, 0x3e, 0xc2, 0xa1, 0x76, 0x1b, 0x23, + 0x9f, 0xf6, 0x23, 0x87, 0x3b, 0x13, 0x94, 0x89, 0x06, 0x28, 0x8d, 0xe7, 0xff, 0x40, 0xe3, 0xc7, + 0x84, 0xaa, 0x9d, 0x33, 0x69, 0xad, 0x07, 0xb7, 0xf3, 0xd9, 0xa4, 0xc5, 0xc2, 0x1d, 0xe3, 0x04, + 0x2d, 0x53, 0xb7, 0x58, 0x47, 0xe4, 0x02, 0x2a, 0x31, 0x0f, 0x3a, 0x72, 0x1a, 0xa0, 0xb5, 0xd5, + 0x30, 0xf6, 0x76, 0x5a, 0x5f, 0x2d, 0xf5, 0x0d, 0xbd, 0x14, 0x44, 0x73, 0x38, 0x79, 0x0c, 0x1f, + 0xe8, 0x73, 0x3e, 0x66, 0x71, 0xe8, 0x9d, 0x33, 0x21, 0xc3, 0xc4, 0x3e, 0xdb, 0x4a, 0x6f, 0x51, + 0x89, 0x1c, 0x82, 0x95, 0xb5, 0xfc, 0xc4, 0x09, 0x59, 0xe8, 0xbb, 0x4e, 0x40, 0xf1, 0x36, 0x46, + 0x21, 0xad, 0x1d, 0x05, 0xbb, 0xb7, 0x4e, 0x5a, 0xb0, 0x9b, 0xd5, 0x3a, 0x92, 0xfb, 0xe1, 0xa8, + 0xcb, 0x92, 0xbe, 0x58, 0x0f, 0x14, 0x6e, 0x61, 0xad, 0x7e, 0x08, 0x5b, 0xc5, 0x13, 0x21, 0x35, + 0x28, 0xbf, 0xc6, 0x69, 0x6a, 0xf0, 0xe4, 0x27, 0xd9, 0x85, 0xf5, 0x3b, 0x27, 0x88, 0x31, 0x75, + 0xb5, 0x0e, 0x0e, 0x4b, 0x4f, 0x8d, 0xfa, 0x31, 0xec, 0x2e, 0xea, 0xf4, 0x2a, 0x1c, 0xcd, 0x03, + 0x20, 0x27, 0x2c, 0xf4, 0xfc, 0xc4, 0xbc, 0x4e, 0xf0, 0xc2, 0x91, 0xee, 0x18, 0x45, 0xea, 0x72, + 0x8e, 0x42, 0x24, 0x2e, 0x4f, 0xc6, 0x51, 0x95, 0x16, 0x32, 0xcd, 0x01, 0xd4, 0xf4, 0xfd, 0xcf, + 0xb1, 0x82, 0xd8, 0x40, 0x5c, 0x16, 0x4a, 0x0c, 0xe5, 0x25, 0x86, 0x23, 0x39, 0xa6, 0x4e, 0x38, + 0x42, 0x85, 0x5d, 0xa7, 0x0b, 0x2a, 0x89, 0x86, 0x90, 0x0e, 0x97, 0xe2, 0xa5, 0x2f, 0xc7, 0x6a, + 0x20, 0x55, 0x69, 0x21, 0xd3, 0xfc, 0x65, 0x0d, 0x4c, 0x2d, 0x72, 0x11, 0x46, 0xb1, 0x2c, 0xd8, + 0xc5, 0xb8, 0xd7, 0x2e, 0xa5, 0xff, 0xc5, 0x2e, 0xe5, 0xfb, 0xed, 0x32, 0x1b, 0x2b, 0x6b, 0xf7, + 0x8c, 0x95, 0xf5, 0xb9, 0xb1, 0xf2, 0xee, 0xf8, 0x58, 0xff, 0x8f, 0xc6, 0x47, 0x17, 0x36, 0x86, + 0x3e, 0x06, 0x9e, 0xb0, 0x2a, 0xea, 0xde, 0x7e, 0xbb, 0xe4, 0x6c, 0xcf, 0x1b, 0x6c, 0x3f, 0x53, + 0x70, 0x7d, 0x59, 0x53, 0x2e, 0xd2, 0x03, 0x70, 0xf3, 0x23, 0xb6, 0xaa, 0xea, 0x83, 0x9e, 0xac, + 0xc0, 0x3c, 0xf3, 0x07, 0x2d, 0x10, 0xd5, 0xbf, 0x01, 0xb3, 0xa0, 0xb6, 0x92, 0x61, 0xff, 0x32, + 0x60, 0x4b, 0x73, 0x5f, 0xc7, 0x32, 0xf1, 0x45, 0x0d, 0xca, 0x31, 0x0f, 0x32, 0x70, 0xcc, 0x03, + 0xd2, 0xcb, 0x5b, 0xa1, 0x9f, 0xb9, 0xef, 0x56, 0xf8, 0x60, 0x4d, 0xba, 0xb0, 0x17, 0x07, 0xf0, + 0x30, 0xbb, 0xc2, 0xa7, 0xe8, 0x32, 0x0f, 0x3d, 0x0d, 0x49, 0xfd, 0xb1, 0xb8, 0xf8, 0x6f, 0xb6, + 0xfa, 0x87, 0x91, 0x5c, 0xb3, 0xf9, 0xa7, 0xf6, 0xed, 0xa7, 0xce, 0x78, 0xf7, 0xa9, 0xa3, 0x60, + 0x46, 0xb3, 0x63, 0x55, 0xb4, 0x66, 0xeb, 0xf1, 0xaa, 0x76, 0xa0, 0x45, 0x12, 0xd2, 0x83, 0xad, + 0xa8, 0xd0, 0x1f, 0xb5, 0x65, 0xb3, 0xb5, 0xbf, 0x72, 0x63, 0xe9, 0x1c, 0x4d, 0xf3, 0x77, 0x03, + 0xaa, 0xf9, 0xfb, 0xbf, 0xc4, 0xd6, 0x9a, 0xb0, 0xe5, 0x87, 0x42, 0xf2, 0xd8, 0xd5, 0x86, 0xd4, + 0x53, 0x63, 0x2e, 0x47, 0x2c, 0xd8, 0xd4, 0x6f, 0xb5, 0xfe, 0x1b, 0x52, 0xa5, 0x59, 0x98, 0xcc, + 0xe7, 0x88, 0x63, 0x6e, 0xc3, 0x36, 0x67, 0x77, 0xbe, 0x87, 0x9e, 0xba, 0xba, 0x15, 0xba, 0xb0, + 0x46, 0x3e, 0x83, 0x6d, 0x7d, 0xae, 0x9d, 0xd8, 0x75, 0x51, 0x08, 0x75, 0x9f, 0x2b, 0x74, 0x3e, + 0xf9, 0xe5, 0x35, 0x54, 0xb2, 0x71, 0x42, 0x76, 0x00, 0xda, 0x47, 0xdd, 0xf3, 0x7e, 0xa7, 0xfb, + 0xea, 0xf2, 0xac, 0xf6, 0x1e, 0xb1, 0x60, 0xf7, 0xe6, 0x82, 0x76, 0x7b, 0x47, 0x97, 0xfd, 0xf3, + 0xeb, 0x4e, 0xf7, 0xec, 0x34, 0xad, 0x18, 0xe4, 0x23, 0x78, 0x78, 0xdc, 0x3b, 0xf9, 0xe1, 0xac, + 0xdb, 0x3f, 0xbe, 0xee, 0x5d, 0x9d, 0xaa, 0xf2, 0xd5, 0xd1, 0x8b, 0xb3, 0x5a, 0xe9, 0xf8, 0x25, + 0x7c, 0xee, 0xb2, 0xc9, 0x32, 0xed, 0x6d, 0x1b, 0xbf, 0x95, 0xbe, 0x78, 0xae, 0xd7, 0x9d, 0xa8, + 0x75, 0x9d, 0xb4, 0x76, 0xb3, 0x6f, 0xab, 0xff, 0x52, 0xf6, 0xc9, 0x0c, 0x38, 0xd8, 0x50, 0x53, + 0xe4, 0xeb, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x06, 0x0c, 0xfc, 0xb3, 0xd6, 0x0a, 0x00, 0x00, } diff --git a/storage/internal/test/conformance/test.proto b/storage/internal/test/conformance/test.proto index 49e913bff40..cf2103b6667 100644 --- a/storage/internal/test/conformance/test.proto +++ b/storage/internal/test/conformance/test.proto @@ -25,6 +25,7 @@ option java_multiple_files = true; message TestFile { repeated SigningV4Test signing_v4_tests = 1; repeated PostPolicyV4Test post_policy_v4_tests = 2; + repeated RetryTest retry_tests = 3; } enum UrlStyle { @@ -83,3 +84,12 @@ message PostPolicyV4Test { PolicyInput policyInput = 2; PolicyOutput policyOutput = 3; } + +message RetryTest { + string description = 1; + repeated string instructions = 2; // e.g. return-503 + repeated string methods = 3; // e.g. storage.objects.get + bool preconditionProvided = 4; + bool expectSuccess = 5; + // repeated string setup = 6; // List of setup steps required for the test. (e.g. bucket created, object created, etc) +} From ff9be594d94a32a0348cdb8dcc6a11cf9eda5082 Mon Sep 17 00:00:00 2001 From: Chris Cotter Date: Thu, 25 Mar 2021 15:34:34 -0400 Subject: [PATCH 05/25] get per-func errors/naming --- storage/conformance_test.go | 57 +++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/storage/conformance_test.go b/storage/conformance_test.go index 822816b503d..3d834efa020 100644 --- a/storage/conformance_test.go +++ b/storage/conformance_test.go @@ -103,33 +103,33 @@ func TestRetryConformance(t *testing.T) { _, _, testFiles := parseFiles(t) for _, testFile := range(testFiles) { for _, tc := range(testFile.RetryTests) { - for _, i := range(tc.Instructions) { + for _, instr := range(tc.Instructions) { for _, m := range(tc.Methods) { - testName := fmt.Sprintf("%v - %v - %v", tc.Description, i, m) - t.Run(testName, func(t *testing.T) { - // Setup bucket and object - // TODO: customize this by operation. - if err := client.Bucket(bucketName).Create(ctx, "myproj", &BucketAttrs{}); err != nil { - t.Errorf("Error creating bucket: %v", err) - } - - w := client.Bucket(bucketName).Object(objName).NewWriter(ctx) - if _, err := w.Write([]byte("abcdef")); err != nil { - t.Errorf("Error writing object to emulator: %v", err) - } - if err := w.Close(); err != nil { - t.Errorf("Error writing object to emulator in Close: %v", err) - } - - // Create wrapped client which will send emulator instructions. - wrapped, err := wrappedClient(i) - if err != nil { - t.Errorf("error creating wrapped client: %v", err) - } - if len(methods[m]) == 0 { - t.Logf("No tests for operation %v", m) - } - for _, f := range(methods[m]) { + if len(methods[m]) == 0 { + t.Logf("No tests for operation %v", m) + } + for i, f := range(methods[m]){ + testName := fmt.Sprintf("%v-%v-%v-%v", tc.Description, instr, m, i) + t.Run(testName, func(t *testing.T) { + // Setup bucket and object + // TODO: customize this by operation. + if err := client.Bucket(bucketName).Create(ctx, "myproj", &BucketAttrs{}); err != nil { + t.Errorf("Error creating bucket: %v", err) + } + + w := client.Bucket(bucketName).Object(objName).NewWriter(ctx) + if _, err := w.Write([]byte("abcdef")); err != nil { + t.Errorf("Error writing object to emulator: %v", err) + } + if err := w.Close(); err != nil { + t.Errorf("Error writing object to emulator in Close: %v", err) + } + + // Create wrapped client which will send emulator instructions. + wrapped, err := wrappedClient(instr) + if err != nil { + t.Errorf("error creating wrapped client: %v", err) + } err = f(ctx, wrapped, tc.PreconditionProvided) if tc.ExpectSuccess && err != nil { t.Errorf("want success, got %v", err) @@ -137,9 +137,10 @@ func TestRetryConformance(t *testing.T) { if !tc.ExpectSuccess && err == nil { t.Errorf("want failure, got success") } - } - }) + }) + } + } } } From 0abbad445cbfff5ce8234804c7645ad778606d0a Mon Sep 17 00:00:00 2001 From: Chris Cotter Date: Mon, 29 Mar 2021 16:06:47 -0400 Subject: [PATCH 06/25] use instruction lists --- storage/conformance_test.go | 22 +-- .../test/conformance/retry_tests.json | 38 +++- storage/internal/test/conformance/test.pb.go | 184 +++++++++++------- storage/internal/test/conformance/test.proto | 6 +- 4 files changed, 162 insertions(+), 88 deletions(-) diff --git a/storage/conformance_test.go b/storage/conformance_test.go index 3d834efa020..155c3b9c892 100644 --- a/storage/conformance_test.go +++ b/storage/conformance_test.go @@ -103,13 +103,13 @@ func TestRetryConformance(t *testing.T) { _, _, testFiles := parseFiles(t) for _, testFile := range(testFiles) { for _, tc := range(testFile.RetryTests) { - for _, instr := range(tc.Instructions) { + for _, instructions := range(tc.Cases) { for _, m := range(tc.Methods) { if len(methods[m]) == 0 { t.Logf("No tests for operation %v", m) } for i, f := range(methods[m]){ - testName := fmt.Sprintf("%v-%v-%v-%v", tc.Description, instr, m, i) + testName := fmt.Sprintf("%v-%v-%v-%v", tc.Description, instructions, m, i) t.Run(testName, func(t *testing.T) { // Setup bucket and object // TODO: customize this by operation. @@ -126,7 +126,7 @@ func TestRetryConformance(t *testing.T) { } // Create wrapped client which will send emulator instructions. - wrapped, err := wrappedClient(instr) + wrapped, err := wrappedClient(instructions.Instructions) if err != nil { t.Errorf("error creating wrapped client: %v", err) } @@ -150,16 +150,15 @@ func TestRetryConformance(t *testing.T) { type withInstruction struct { rt http.RoundTripper - instr string - retries int + instructions []string } func (wi *withInstruction) RoundTrip(r *http.Request) (*http.Response, error) { - if wi.retries > 0 { - r.Header.Set("x-goog-testbench-instructions", wi.instr) - wi.retries -= 1 + if len(wi.instructions) > 0 { + r.Header.Set("x-goog-testbench-instructions", wi.instructions[0]) + wi.instructions = wi.instructions[1:] } - log.Printf("Request: %+v\nRetries: %v\n\n", r, wi.retries) + log.Printf("Request: %+v\nRemaining instructions: %v\n\n", r, wi.instructions) resp, err := wi.rt.RoundTrip(r) //if err != nil{ // log.Printf("Error: %+v", err) @@ -168,7 +167,7 @@ func (wi *withInstruction) RoundTrip(r *http.Request) (*http.Response, error) { } // Create custom client that sends instruction -func wrappedClient(instruction string) (*Client, error) { +func wrappedClient(instructions []string) (*Client, error) { ctx := context.Background() base := http.DefaultTransport trans, err := htransport.NewTransport(ctx, base, option.WithScopes(raw.DevstorageFullControlScope), @@ -179,8 +178,7 @@ func wrappedClient(instruction string) (*Client, error) { c := http.Client{Transport: trans} // Add RoundTripper to the created HTTP client. - instr := instruction - wrappedTrans := &withInstruction{rt: c.Transport, instr: instr, retries: 2} + wrappedTrans := &withInstruction{rt: c.Transport, instructions: instructions} c.Transport = wrappedTrans // Supply this client to storage.NewClient diff --git a/storage/internal/test/conformance/retry_tests.json b/storage/internal/test/conformance/retry_tests.json index fae7862dd4e..aef50e2234a 100644 --- a/storage/internal/test/conformance/retry_tests.json +++ b/storage/internal/test/conformance/retry_tests.json @@ -2,21 +2,51 @@ "retryTests": [ { "description": "always idempotent, retryable errors", - "instructions": ["return-503", "reset-connection"], - "methods": ["storage.objects.get", "storage.buckets.get"], + "cases": [ + { + "instructions": ["return-503", "return-503", "return-503"] + }, + { + "instructions": ["reset-connection", "reset-connection", "reset-connection"] + }, + { + "instructions": ["reset-connection", "return-503", "return-503"] + } + ], "methods": ["storage.objects.get", "storage.buckets.get"], "preconditionProvided": false, "expectSuccess": true }, { "description": "always idempotent, retryable errors", - "instructions": ["return-503", "reset-connection"], + "cases": [ + { + "instructions": ["return-503", "return-503", "return-503"] + }, + { + "instructions": ["reset-connection", "reset-connection", "reset-connection"] + }, + { + "instructions": ["reset-connection", "return-503", "return-503"] + } + ], "methods": ["storage.objects.get", "storage.buckets.get"], "preconditionProvided": true, "expectSuccess": true }, { "description": "always idempotent, non-retryable errors", - "instructions": ["return-400", "return-401"], + "cases": [ + { + "instructions": [ + "return-400", + "return-400", + "return-400" + ] + }, + { + "instructions": ["return-401", "return-401", "return-401"] + } + ], "methods": ["storage.objects.get", "storage.buckets.get"], "preconditionProvided": false, "expectSuccess": false diff --git a/storage/internal/test/conformance/test.pb.go b/storage/internal/test/conformance/test.pb.go index a99356c2d8e..41a7f137365 100644 --- a/storage/internal/test/conformance/test.pb.go +++ b/storage/internal/test/conformance/test.pb.go @@ -554,22 +554,61 @@ func (m *PostPolicyV4Test) GetPolicyOutput() *PolicyOutput { return nil } -type RetryTest struct { - Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` - Instructions []string `protobuf:"bytes,2,rep,name=instructions,proto3" json:"instructions,omitempty"` - Methods []string `protobuf:"bytes,3,rep,name=methods,proto3" json:"methods,omitempty"` - PreconditionProvided bool `protobuf:"varint,4,opt,name=preconditionProvided,proto3" json:"preconditionProvided,omitempty"` - ExpectSuccess bool `protobuf:"varint,5,opt,name=expectSuccess,proto3" json:"expectSuccess,omitempty"` +type InstructionList struct { + Instructions []string `protobuf:"bytes,1,rep,name=instructions,proto3" json:"instructions,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } +func (m *InstructionList) Reset() { *m = InstructionList{} } +func (m *InstructionList) String() string { return proto.CompactTextString(m) } +func (*InstructionList) ProtoMessage() {} +func (*InstructionList) Descriptor() ([]byte, []int) { + return fileDescriptor_c161fcfdc0c3ff1e, []int{7} +} + +func (m *InstructionList) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_InstructionList.Unmarshal(m, b) +} +func (m *InstructionList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_InstructionList.Marshal(b, m, deterministic) +} +func (m *InstructionList) XXX_Merge(src proto.Message) { + xxx_messageInfo_InstructionList.Merge(m, src) +} +func (m *InstructionList) XXX_Size() int { + return xxx_messageInfo_InstructionList.Size(m) +} +func (m *InstructionList) XXX_DiscardUnknown() { + xxx_messageInfo_InstructionList.DiscardUnknown(m) +} + +var xxx_messageInfo_InstructionList proto.InternalMessageInfo + +func (m *InstructionList) GetInstructions() []string { + if m != nil { + return m.Instructions + } + return nil +} + +type RetryTest struct { + Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` + Cases []*InstructionList `protobuf:"bytes,2,rep,name=cases,proto3" json:"cases,omitempty"` + Methods []string `protobuf:"bytes,3,rep,name=methods,proto3" json:"methods,omitempty"` + PreconditionProvided bool `protobuf:"varint,4,opt,name=preconditionProvided,proto3" json:"preconditionProvided,omitempty"` + ExpectSuccess bool `protobuf:"varint,5,opt,name=expectSuccess,proto3" json:"expectSuccess,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + func (m *RetryTest) Reset() { *m = RetryTest{} } func (m *RetryTest) String() string { return proto.CompactTextString(m) } func (*RetryTest) ProtoMessage() {} func (*RetryTest) Descriptor() ([]byte, []int) { - return fileDescriptor_c161fcfdc0c3ff1e, []int{7} + return fileDescriptor_c161fcfdc0c3ff1e, []int{8} } func (m *RetryTest) XXX_Unmarshal(b []byte) error { @@ -597,9 +636,9 @@ func (m *RetryTest) GetDescription() string { return "" } -func (m *RetryTest) GetInstructions() []string { +func (m *RetryTest) GetCases() []*InstructionList { if m != nil { - return m.Instructions + return m.Cases } return nil } @@ -638,73 +677,76 @@ func init() { proto.RegisterType((*PolicyOutput)(nil), "google.cloud.conformance.storage.v1.PolicyOutput") proto.RegisterMapType((map[string]string)(nil), "google.cloud.conformance.storage.v1.PolicyOutput.FieldsEntry") proto.RegisterType((*PostPolicyV4Test)(nil), "google.cloud.conformance.storage.v1.PostPolicyV4Test") + proto.RegisterType((*InstructionList)(nil), "google.cloud.conformance.storage.v1.InstructionList") proto.RegisterType((*RetryTest)(nil), "google.cloud.conformance.storage.v1.RetryTest") } func init() { proto.RegisterFile("test.proto", fileDescriptor_c161fcfdc0c3ff1e) } var fileDescriptor_c161fcfdc0c3ff1e = []byte{ - // 992 bytes of a gzipped FileDescriptorProto + // 1018 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xdd, 0x6e, 0xe3, 0x44, - 0x14, 0xc6, 0x49, 0x7f, 0x92, 0xe3, 0xb6, 0x1b, 0x86, 0x2e, 0x32, 0xb9, 0x80, 0x28, 0x20, 0x51, - 0x90, 0xf0, 0x6e, 0x43, 0x57, 0x5a, 0x2a, 0x10, 0xea, 0xdf, 0x6e, 0x2b, 0xba, 0x6d, 0x98, 0x24, - 0x5d, 0xad, 0x84, 0x14, 0x39, 0xf6, 0x49, 0x62, 0xd6, 0xf1, 0xb8, 0x33, 0xe3, 0x6a, 0xf3, 0x1e, - 0xbc, 0x00, 0xb7, 0xbc, 0x07, 0xcf, 0xc1, 0x15, 0x12, 0x8f, 0x81, 0x3c, 0x63, 0x3b, 0xce, 0x6e, - 0x2a, 0x25, 0xfc, 0xdc, 0xe5, 0x9c, 0x33, 0xdf, 0xf7, 0x79, 0xce, 0x7c, 0x73, 0x26, 0x00, 0x12, - 0x85, 0xb4, 0x23, 0xce, 0x24, 0x23, 0x9f, 0x8e, 0x18, 0x1b, 0x05, 0x68, 0xbb, 0x01, 0x8b, 0x3d, - 0xdb, 0x65, 0xe1, 0x90, 0xf1, 0x89, 0x13, 0xba, 0x68, 0x0b, 0xc9, 0xb8, 0x33, 0x42, 0xfb, 0x6e, - 0xbf, 0xfe, 0x89, 0x5e, 0xf4, 0x48, 0x41, 0x06, 0xf1, 0xf0, 0x91, 0xf4, 0x27, 0x28, 0xa4, 0x33, - 0x89, 0x34, 0x4b, 0xf3, 0xd7, 0x12, 0x54, 0xba, 0x28, 0xe4, 0x33, 0x3f, 0x40, 0xf2, 0x13, 0xd4, - 0x84, 0x3f, 0x0a, 0xfd, 0x70, 0xd4, 0xbf, 0x3b, 0xe8, 0x27, 0x5a, 0xc2, 0x32, 0x1a, 0xe5, 0x3d, - 0xb3, 0xd5, 0xb2, 0x97, 0x50, 0xb3, 0x3b, 0x1a, 0x7c, 0x73, 0x90, 0x30, 0xd2, 0x1d, 0x51, 0x0c, - 0x05, 0x19, 0xc2, 0x6e, 0xc4, 0x84, 0xec, 0x47, 0x2c, 0xf0, 0xdd, 0xe9, 0x4c, 0xa1, 0xa4, 0x14, - 0x9e, 0x2c, 0xa5, 0xd0, 0x66, 0x42, 0xb6, 0x15, 0x3e, 0x15, 0x79, 0x3f, 0x7a, 0x2b, 0x23, 0xc8, - 0x35, 0x98, 0x1c, 0x25, 0x9f, 0xa6, 0xf4, 0x65, 0x45, 0x6f, 0x2f, 0x45, 0x4f, 0x13, 0x9c, 0xe2, - 0x05, 0x9e, 0xfd, 0x14, 0xcd, 0x3f, 0x37, 0x60, 0x7b, 0x6e, 0x6b, 0xa4, 0x0e, 0x95, 0xa1, 0x1f, - 0xe0, 0x95, 0x33, 0x41, 0xcb, 0x68, 0x18, 0x7b, 0x55, 0x9a, 0xc7, 0xa4, 0x01, 0xa6, 0x87, 0xc2, - 0xe5, 0x7e, 0x24, 0x7d, 0x16, 0x5a, 0x25, 0x55, 0x2e, 0xa6, 0xc8, 0x87, 0xb0, 0x31, 0x88, 0xdd, - 0xd7, 0x28, 0xad, 0xb2, 0x2a, 0xa6, 0x51, 0x92, 0x67, 0x83, 0x9f, 0xd1, 0x95, 0xd6, 0x9a, 0xce, - 0xeb, 0x28, 0xc9, 0x4f, 0x50, 0x8e, 0x99, 0x67, 0xad, 0xeb, 0xbc, 0x8e, 0xc8, 0xc7, 0x00, 0xf8, - 0x26, 0xf2, 0xb9, 0xa3, 0x84, 0x36, 0x1a, 0xc6, 0x5e, 0x99, 0x16, 0x32, 0xe4, 0x29, 0x54, 0xf3, - 0xe3, 0xb6, 0x36, 0x1b, 0xc6, 0x9e, 0xd9, 0xaa, 0x67, 0x6d, 0xc8, 0x0c, 0x61, 0x77, 0xb3, 0x15, - 0x74, 0xb6, 0x38, 0xd9, 0x03, 0xbe, 0x89, 0xd0, 0x95, 0xe8, 0xf5, 0x78, 0x60, 0x55, 0xf4, 0x1e, - 0x0a, 0x29, 0xf2, 0x0a, 0x36, 0xc7, 0xe8, 0x78, 0xc8, 0x85, 0x55, 0x55, 0x0d, 0xfe, 0x7e, 0x75, - 0x87, 0xd8, 0xe7, 0x9a, 0xe1, 0x2c, 0x94, 0x7c, 0x4a, 0x33, 0x3e, 0xc2, 0xa1, 0x76, 0x1b, 0x23, - 0x9f, 0xf6, 0x23, 0x87, 0x3b, 0x13, 0x94, 0x89, 0x06, 0x28, 0x8d, 0xe7, 0xff, 0x40, 0xe3, 0xc7, - 0x84, 0xaa, 0x9d, 0x33, 0x69, 0xad, 0x07, 0xb7, 0xf3, 0xd9, 0xa4, 0xc5, 0xc2, 0x1d, 0xe3, 0x04, - 0x2d, 0x53, 0xb7, 0x58, 0x47, 0xe4, 0x02, 0x2a, 0x31, 0x0f, 0x3a, 0x72, 0x1a, 0xa0, 0xb5, 0xd5, - 0x30, 0xf6, 0x76, 0x5a, 0x5f, 0x2d, 0xf5, 0x0d, 0xbd, 0x14, 0x44, 0x73, 0x38, 0x79, 0x0c, 0x1f, - 0xe8, 0x73, 0x3e, 0x66, 0x71, 0xe8, 0x9d, 0x33, 0x21, 0xc3, 0xc4, 0x3e, 0xdb, 0x4a, 0x6f, 0x51, - 0x89, 0x1c, 0x82, 0x95, 0xb5, 0xfc, 0xc4, 0x09, 0x59, 0xe8, 0xbb, 0x4e, 0x40, 0xf1, 0x36, 0x46, - 0x21, 0xad, 0x1d, 0x05, 0xbb, 0xb7, 0x4e, 0x5a, 0xb0, 0x9b, 0xd5, 0x3a, 0x92, 0xfb, 0xe1, 0xa8, - 0xcb, 0x92, 0xbe, 0x58, 0x0f, 0x14, 0x6e, 0x61, 0xad, 0x7e, 0x08, 0x5b, 0xc5, 0x13, 0x21, 0x35, - 0x28, 0xbf, 0xc6, 0x69, 0x6a, 0xf0, 0xe4, 0x27, 0xd9, 0x85, 0xf5, 0x3b, 0x27, 0x88, 0x31, 0x75, - 0xb5, 0x0e, 0x0e, 0x4b, 0x4f, 0x8d, 0xfa, 0x31, 0xec, 0x2e, 0xea, 0xf4, 0x2a, 0x1c, 0xcd, 0x03, - 0x20, 0x27, 0x2c, 0xf4, 0xfc, 0xc4, 0xbc, 0x4e, 0xf0, 0xc2, 0x91, 0xee, 0x18, 0x45, 0xea, 0x72, - 0x8e, 0x42, 0x24, 0x2e, 0x4f, 0xc6, 0x51, 0x95, 0x16, 0x32, 0xcd, 0x01, 0xd4, 0xf4, 0xfd, 0xcf, - 0xb1, 0x82, 0xd8, 0x40, 0x5c, 0x16, 0x4a, 0x0c, 0xe5, 0x25, 0x86, 0x23, 0x39, 0xa6, 0x4e, 0x38, - 0x42, 0x85, 0x5d, 0xa7, 0x0b, 0x2a, 0x89, 0x86, 0x90, 0x0e, 0x97, 0xe2, 0xa5, 0x2f, 0xc7, 0x6a, - 0x20, 0x55, 0x69, 0x21, 0xd3, 0xfc, 0x65, 0x0d, 0x4c, 0x2d, 0x72, 0x11, 0x46, 0xb1, 0x2c, 0xd8, - 0xc5, 0xb8, 0xd7, 0x2e, 0xa5, 0xff, 0xc5, 0x2e, 0xe5, 0xfb, 0xed, 0x32, 0x1b, 0x2b, 0x6b, 0xf7, - 0x8c, 0x95, 0xf5, 0xb9, 0xb1, 0xf2, 0xee, 0xf8, 0x58, 0xff, 0x8f, 0xc6, 0x47, 0x17, 0x36, 0x86, - 0x3e, 0x06, 0x9e, 0xb0, 0x2a, 0xea, 0xde, 0x7e, 0xbb, 0xe4, 0x6c, 0xcf, 0x1b, 0x6c, 0x3f, 0x53, - 0x70, 0x7d, 0x59, 0x53, 0x2e, 0xd2, 0x03, 0x70, 0xf3, 0x23, 0xb6, 0xaa, 0xea, 0x83, 0x9e, 0xac, - 0xc0, 0x3c, 0xf3, 0x07, 0x2d, 0x10, 0xd5, 0xbf, 0x01, 0xb3, 0xa0, 0xb6, 0x92, 0x61, 0xff, 0x32, - 0x60, 0x4b, 0x73, 0x5f, 0xc7, 0x32, 0xf1, 0x45, 0x0d, 0xca, 0x31, 0x0f, 0x32, 0x70, 0xcc, 0x03, - 0xd2, 0xcb, 0x5b, 0xa1, 0x9f, 0xb9, 0xef, 0x56, 0xf8, 0x60, 0x4d, 0xba, 0xb0, 0x17, 0x07, 0xf0, - 0x30, 0xbb, 0xc2, 0xa7, 0xe8, 0x32, 0x0f, 0x3d, 0x0d, 0x49, 0xfd, 0xb1, 0xb8, 0xf8, 0x6f, 0xb6, - 0xfa, 0x87, 0x91, 0x5c, 0xb3, 0xf9, 0xa7, 0xf6, 0xed, 0xa7, 0xce, 0x78, 0xf7, 0xa9, 0xa3, 0x60, - 0x46, 0xb3, 0x63, 0x55, 0xb4, 0x66, 0xeb, 0xf1, 0xaa, 0x76, 0xa0, 0x45, 0x12, 0xd2, 0x83, 0xad, - 0xa8, 0xd0, 0x1f, 0xb5, 0x65, 0xb3, 0xb5, 0xbf, 0x72, 0x63, 0xe9, 0x1c, 0x4d, 0xf3, 0x77, 0x03, - 0xaa, 0xf9, 0xfb, 0xbf, 0xc4, 0xd6, 0x9a, 0xb0, 0xe5, 0x87, 0x42, 0xf2, 0xd8, 0xd5, 0x86, 0xd4, - 0x53, 0x63, 0x2e, 0x47, 0x2c, 0xd8, 0xd4, 0x6f, 0xb5, 0xfe, 0x1b, 0x52, 0xa5, 0x59, 0x98, 0xcc, - 0xe7, 0x88, 0x63, 0x6e, 0xc3, 0x36, 0x67, 0x77, 0xbe, 0x87, 0x9e, 0xba, 0xba, 0x15, 0xba, 0xb0, - 0x46, 0x3e, 0x83, 0x6d, 0x7d, 0xae, 0x9d, 0xd8, 0x75, 0x51, 0x08, 0x75, 0x9f, 0x2b, 0x74, 0x3e, - 0xf9, 0xe5, 0x35, 0x54, 0xb2, 0x71, 0x42, 0x76, 0x00, 0xda, 0x47, 0xdd, 0xf3, 0x7e, 0xa7, 0xfb, - 0xea, 0xf2, 0xac, 0xf6, 0x1e, 0xb1, 0x60, 0xf7, 0xe6, 0x82, 0x76, 0x7b, 0x47, 0x97, 0xfd, 0xf3, - 0xeb, 0x4e, 0xf7, 0xec, 0x34, 0xad, 0x18, 0xe4, 0x23, 0x78, 0x78, 0xdc, 0x3b, 0xf9, 0xe1, 0xac, - 0xdb, 0x3f, 0xbe, 0xee, 0x5d, 0x9d, 0xaa, 0xf2, 0xd5, 0xd1, 0x8b, 0xb3, 0x5a, 0xe9, 0xf8, 0x25, - 0x7c, 0xee, 0xb2, 0xc9, 0x32, 0xed, 0x6d, 0x1b, 0xbf, 0x95, 0xbe, 0x78, 0xae, 0xd7, 0x9d, 0xa8, - 0x75, 0x9d, 0xb4, 0x76, 0xb3, 0x6f, 0xab, 0xff, 0x52, 0xf6, 0xc9, 0x0c, 0x38, 0xd8, 0x50, 0x53, - 0xe4, 0xeb, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x06, 0x0c, 0xfc, 0xb3, 0xd6, 0x0a, 0x00, 0x00, + 0x14, 0xc6, 0x49, 0xd3, 0x26, 0x27, 0xfd, 0x09, 0x43, 0x17, 0x99, 0x5c, 0x40, 0x14, 0x90, 0x28, + 0x48, 0x78, 0xb7, 0xa1, 0x95, 0x96, 0x0a, 0x84, 0xfa, 0xb7, 0xdb, 0x42, 0xb7, 0x0d, 0x93, 0xa4, + 0xab, 0x95, 0x90, 0x22, 0xd7, 0x3e, 0x49, 0xcc, 0x3a, 0x1e, 0x77, 0x66, 0x5c, 0x6d, 0xde, 0x83, + 0x17, 0xe0, 0x96, 0x97, 0xe2, 0x0a, 0x89, 0x1b, 0xde, 0x01, 0x79, 0xc6, 0x76, 0x9c, 0x6e, 0x2a, + 0x25, 0xc0, 0xde, 0x79, 0xce, 0x99, 0xf3, 0x7d, 0x33, 0x67, 0xbe, 0xf9, 0x3c, 0x00, 0x12, 0x85, + 0xb4, 0x42, 0xce, 0x24, 0x23, 0x9f, 0x0e, 0x19, 0x1b, 0xfa, 0x68, 0x39, 0x3e, 0x8b, 0x5c, 0xcb, + 0x61, 0xc1, 0x80, 0xf1, 0xb1, 0x1d, 0x38, 0x68, 0x09, 0xc9, 0xb8, 0x3d, 0x44, 0xeb, 0x6e, 0xb7, + 0xfe, 0x89, 0x9e, 0xf4, 0x58, 0x95, 0xdc, 0x44, 0x83, 0xc7, 0xd2, 0x1b, 0xa3, 0x90, 0xf6, 0x38, + 0xd4, 0x28, 0xcd, 0xdf, 0x0a, 0x50, 0xee, 0xa2, 0x90, 0xcf, 0x3c, 0x1f, 0xc9, 0xcf, 0x50, 0x13, + 0xde, 0x30, 0xf0, 0x82, 0x61, 0xff, 0x6e, 0xaf, 0x1f, 0x73, 0x09, 0xd3, 0x68, 0x14, 0x77, 0xaa, + 0xad, 0x96, 0xb5, 0x00, 0x9b, 0xd5, 0xd1, 0xc5, 0xd7, 0x7b, 0x31, 0x22, 0xdd, 0x14, 0xf9, 0xa1, + 0x20, 0x03, 0xd8, 0x0e, 0x99, 0x90, 0xfd, 0x90, 0xf9, 0x9e, 0x33, 0x99, 0x32, 0x14, 0x14, 0xc3, + 0xfe, 0x42, 0x0c, 0x6d, 0x26, 0x64, 0x5b, 0xd5, 0x27, 0x24, 0xef, 0x87, 0xf7, 0x22, 0x82, 0x5c, + 0x41, 0x95, 0xa3, 0xe4, 0x93, 0x04, 0xbe, 0xa8, 0xe0, 0xad, 0x85, 0xe0, 0x69, 0x5c, 0xa7, 0x70, + 0x81, 0xa7, 0x9f, 0xa2, 0xf9, 0xe7, 0x2a, 0x6c, 0xcc, 0x6c, 0x8d, 0xd4, 0xa1, 0x3c, 0xf0, 0x7c, + 0xbc, 0xb4, 0xc7, 0x68, 0x1a, 0x0d, 0x63, 0xa7, 0x42, 0xb3, 0x31, 0x69, 0x40, 0xd5, 0x45, 0xe1, + 0x70, 0x2f, 0x94, 0x1e, 0x0b, 0xcc, 0x82, 0x4a, 0xe7, 0x43, 0xe4, 0x43, 0x58, 0xbd, 0x89, 0x9c, + 0xd7, 0x28, 0xcd, 0xa2, 0x4a, 0x26, 0xa3, 0x38, 0xce, 0x6e, 0x7e, 0x41, 0x47, 0x9a, 0x2b, 0x3a, + 0xae, 0x47, 0x71, 0x7c, 0x8c, 0x72, 0xc4, 0x5c, 0xb3, 0xa4, 0xe3, 0x7a, 0x44, 0x3e, 0x06, 0xc0, + 0x37, 0xa1, 0xc7, 0x6d, 0x45, 0xb4, 0xda, 0x30, 0x76, 0x8a, 0x34, 0x17, 0x21, 0x4f, 0xa1, 0x92, + 0x1d, 0xb7, 0xb9, 0xd6, 0x30, 0x76, 0xaa, 0xad, 0x7a, 0xda, 0x86, 0x54, 0x10, 0x56, 0x37, 0x9d, + 0x41, 0xa7, 0x93, 0xe3, 0x3d, 0xe0, 0x9b, 0x10, 0x1d, 0x89, 0x6e, 0x8f, 0xfb, 0x66, 0x59, 0xef, + 0x21, 0x17, 0x22, 0xaf, 0x60, 0x6d, 0x84, 0xb6, 0x8b, 0x5c, 0x98, 0x15, 0xd5, 0xe0, 0xef, 0x97, + 0x57, 0x88, 0x75, 0xa6, 0x11, 0x4e, 0x03, 0xc9, 0x27, 0x34, 0xc5, 0x23, 0x1c, 0x6a, 0xb7, 0x11, + 0xf2, 0x49, 0x3f, 0xb4, 0xb9, 0x3d, 0x46, 0x19, 0x73, 0x80, 0xe2, 0x78, 0xfe, 0x2f, 0x38, 0x7e, + 0x8a, 0xa1, 0xda, 0x19, 0x92, 0xe6, 0xda, 0xba, 0x9d, 0x8d, 0xc6, 0x2d, 0x16, 0xce, 0x08, 0xc7, + 0x68, 0x56, 0x75, 0x8b, 0xf5, 0x88, 0x9c, 0x43, 0x39, 0xe2, 0x7e, 0x47, 0x4e, 0x7c, 0x34, 0xd7, + 0x1b, 0xc6, 0xce, 0x66, 0xeb, 0xab, 0x85, 0xd6, 0xd0, 0x4b, 0x8a, 0x68, 0x56, 0x4e, 0x9e, 0xc0, + 0x07, 0xfa, 0x9c, 0x8f, 0x58, 0x14, 0xb8, 0x67, 0x4c, 0xc8, 0x20, 0x96, 0xcf, 0x86, 0xe2, 0x9b, + 0x97, 0x22, 0x07, 0x60, 0xa6, 0x2d, 0x3f, 0xb6, 0x03, 0x16, 0x78, 0x8e, 0xed, 0x53, 0xbc, 0x8d, + 0x50, 0x48, 0x73, 0x53, 0x95, 0x3d, 0x98, 0x27, 0x2d, 0xd8, 0x4e, 0x73, 0x1d, 0xc9, 0xbd, 0x60, + 0xd8, 0x65, 0x71, 0x5f, 0xcc, 0x2d, 0x55, 0x37, 0x37, 0x57, 0x3f, 0x80, 0xf5, 0xfc, 0x89, 0x90, + 0x1a, 0x14, 0x5f, 0xe3, 0x24, 0x11, 0x78, 0xfc, 0x49, 0xb6, 0xa1, 0x74, 0x67, 0xfb, 0x11, 0x26, + 0xaa, 0xd6, 0x83, 0x83, 0xc2, 0x53, 0xa3, 0x7e, 0x04, 0xdb, 0xf3, 0x3a, 0xbd, 0x0c, 0x46, 0x73, + 0x0f, 0xc8, 0x31, 0x0b, 0x5c, 0x2f, 0x16, 0xaf, 0xed, 0xbf, 0xb0, 0xa5, 0x33, 0x42, 0x91, 0xa8, + 0x9c, 0xa3, 0x10, 0xb1, 0xca, 0x63, 0x3b, 0xaa, 0xd0, 0x5c, 0xa4, 0x79, 0x03, 0x35, 0x7d, 0xff, + 0xb3, 0x5a, 0x41, 0x2c, 0x20, 0x0e, 0x0b, 0x24, 0x06, 0xf2, 0x02, 0x83, 0xa1, 0x1c, 0x51, 0x3b, + 0x18, 0xa2, 0xaa, 0x2d, 0xd1, 0x39, 0x99, 0x98, 0x43, 0x48, 0x9b, 0x4b, 0xf1, 0xd2, 0x93, 0x23, + 0x65, 0x48, 0x15, 0x9a, 0x8b, 0x34, 0x7f, 0x5d, 0x81, 0xaa, 0x26, 0x39, 0x0f, 0xc2, 0x48, 0xe6, + 0xe4, 0x62, 0x3c, 0x28, 0x97, 0xc2, 0x3b, 0x91, 0x4b, 0xf1, 0x61, 0xb9, 0x4c, 0x6d, 0x65, 0xe5, + 0x01, 0x5b, 0x29, 0xcd, 0xd8, 0xca, 0xdb, 0xf6, 0x51, 0xfa, 0x9f, 0xec, 0xa3, 0x0b, 0xab, 0x03, + 0x0f, 0x7d, 0x57, 0x98, 0x65, 0x75, 0x6f, 0xbf, 0x5d, 0xd0, 0xdb, 0xb3, 0x06, 0x5b, 0xcf, 0x54, + 0xb9, 0xbe, 0xac, 0x09, 0x16, 0xe9, 0x01, 0x38, 0xd9, 0x11, 0x9b, 0x15, 0xb5, 0xa0, 0xfd, 0x25, + 0x90, 0xa7, 0xfa, 0xa0, 0x39, 0xa0, 0xfa, 0x37, 0x50, 0xcd, 0xb1, 0x2d, 0x25, 0xd8, 0xbf, 0x0c, + 0x58, 0xd7, 0xd8, 0x57, 0x91, 0x8c, 0x75, 0x51, 0x83, 0x62, 0xc4, 0xfd, 0xb4, 0x38, 0xe2, 0x3e, + 0xe9, 0x65, 0xad, 0xd0, 0xbf, 0xb9, 0xef, 0x96, 0x58, 0xb0, 0x06, 0x9d, 0xdb, 0x8b, 0x3d, 0x78, + 0x94, 0x5e, 0xe1, 0x13, 0x74, 0x98, 0x8b, 0xae, 0x2e, 0x49, 0xf4, 0x31, 0x3f, 0xf9, 0x5f, 0xb6, + 0xfa, 0x87, 0x11, 0x5f, 0xb3, 0xd9, 0x5f, 0xed, 0xfd, 0x5f, 0x9d, 0xf1, 0xf6, 0xaf, 0x8e, 0x42, + 0x35, 0x9c, 0x1e, 0xab, 0x82, 0xad, 0xb6, 0x9e, 0x2c, 0x2b, 0x07, 0x9a, 0x07, 0x21, 0x3d, 0x58, + 0x0f, 0x73, 0xfd, 0x51, 0x5b, 0xae, 0xb6, 0x76, 0x97, 0x6e, 0x2c, 0x9d, 0x81, 0x69, 0xee, 0xc3, + 0xd6, 0x79, 0x20, 0x24, 0x8f, 0x9c, 0x78, 0xe5, 0x17, 0x9e, 0x90, 0xa4, 0x09, 0xeb, 0xde, 0x34, + 0x24, 0x12, 0xf3, 0x99, 0x89, 0x35, 0xff, 0x36, 0xa0, 0x92, 0x3d, 0x1b, 0x16, 0xe8, 0xc8, 0x0f, + 0x50, 0x72, 0x6c, 0x81, 0xa9, 0x1e, 0xf6, 0x16, 0x5a, 0xf6, 0xbd, 0x85, 0x51, 0x0d, 0x41, 0x4c, + 0x58, 0xd3, 0x4f, 0x01, 0xfd, 0xca, 0xa9, 0xd0, 0x74, 0x18, 0xdb, 0x7f, 0xc8, 0x31, 0x53, 0x79, + 0x9b, 0xb3, 0x3b, 0xcf, 0x45, 0x57, 0x39, 0x43, 0x99, 0xce, 0xcd, 0x91, 0xcf, 0x60, 0x43, 0xcb, + 0xa6, 0x13, 0x39, 0x0e, 0x0a, 0xa1, 0xec, 0xa2, 0x4c, 0x67, 0x83, 0x5f, 0x5e, 0x41, 0x39, 0x75, + 0x2b, 0xb2, 0x09, 0xd0, 0x3e, 0xec, 0x9e, 0xf5, 0x3b, 0xdd, 0x57, 0x17, 0xa7, 0xb5, 0xf7, 0x88, + 0x09, 0xdb, 0xd7, 0xe7, 0xb4, 0xdb, 0x3b, 0xbc, 0xe8, 0x9f, 0x5d, 0x75, 0xba, 0xa7, 0x27, 0x49, + 0xc6, 0x20, 0x1f, 0xc1, 0xa3, 0xa3, 0xde, 0xf1, 0x8f, 0xa7, 0xdd, 0xfe, 0xd1, 0x55, 0xef, 0xf2, + 0x44, 0xa5, 0x2f, 0x0f, 0x5f, 0x9c, 0xd6, 0x0a, 0x47, 0x2f, 0xe1, 0x73, 0x87, 0x8d, 0x17, 0x69, + 0x43, 0xdb, 0xf8, 0xbd, 0xf0, 0xc5, 0x73, 0x3d, 0xef, 0x58, 0xcd, 0xeb, 0x24, 0xb9, 0xeb, 0x5d, + 0x4b, 0x3d, 0xd5, 0xac, 0xe3, 0x69, 0xe1, 0xcd, 0xaa, 0x32, 0xa9, 0xaf, 0xff, 0x09, 0x00, 0x00, + 0xff, 0xff, 0x5e, 0x7a, 0x44, 0x3f, 0x35, 0x0b, 0x00, 0x00, } diff --git a/storage/internal/test/conformance/test.proto b/storage/internal/test/conformance/test.proto index cf2103b6667..abcaa5115e6 100644 --- a/storage/internal/test/conformance/test.proto +++ b/storage/internal/test/conformance/test.proto @@ -85,9 +85,13 @@ message PostPolicyV4Test { PolicyOutput policyOutput = 3; } +message InstructionList { + repeated string instructions = 1; // e.g. return-503 +} + message RetryTest { string description = 1; - repeated string instructions = 2; // e.g. return-503 + repeated InstructionList cases = 2; repeated string methods = 3; // e.g. storage.objects.get bool preconditionProvided = 4; bool expectSuccess = 5; From 87f998eb3723d21cec94eb19446c5fbd7181d26f Mon Sep 17 00:00:00 2001 From: Chris Cotter Date: Fri, 2 Apr 2021 11:51:32 -0400 Subject: [PATCH 07/25] update schema with fixtures --- storage/conformance_test.go | 126 +++++++--- .../test/conformance/retry_tests.json | 30 +-- storage/internal/test/conformance/test.pb.go | 238 ++++++++++++------ storage/internal/test/conformance/test.proto | 23 +- 4 files changed, 286 insertions(+), 131 deletions(-) diff --git a/storage/conformance_test.go b/storage/conformance_test.go index 155c3b9c892..9a1e0da50d4 100644 --- a/storage/conformance_test.go +++ b/storage/conformance_test.go @@ -31,6 +31,7 @@ import ( "testing" "time" + "cloud.google.com/go/internal/uid" storage_v1_tests "cloud.google.com/go/storage/internal/test/conformance" "github.com/golang/protobuf/jsonpb" "github.com/google/go-cmp/cmp" @@ -39,9 +40,72 @@ import ( htransport "google.golang.org/api/transport/http" ) -type retryFunc func(ctx context.Context, c *Client, preconditions bool) error +var ( + bucketIDs = uid.NewSpace("bucket", nil) + objectIDs = uid.NewSpace("object", nil) + notificationIDs = uid.NewSpace("notification", nil) + projectID = "my-project-id" + serviceAccountEmail = "my-sevice-account@my-project-id.iam.gserviceaccount.com" +) + +// Holds the fixtures for a particular test case. Only the necessary fields will +// be populated; others will be nil. +type fixtures struct { + bucket *BucketAttrs + object *ObjectAttrs + notification *Notification + hmacKey *HMACKey +} + +func (fs *fixtures) populate(ctx context.Context, c *Client, fixture storage_v1_tests.Fixture) error { + switch fixture { + case storage_v1_tests.Fixture_BUCKET: + bkt := c.Bucket(bucketIDs.New()) + if err := bkt.Create(ctx, projectID, &BucketAttrs{}); err != nil { + return fmt.Errorf("creating bucket: %v", err) + } + attrs, err := bkt.Attrs(ctx) + if err != nil { + return fmt.Errorf("getting bucket attrs: %v", err) + } + fs.bucket = attrs + case storage_v1_tests.Fixture_OBJECT: + // Assumes bucket has been populated first. + obj := c.Bucket(fs.bucket.Name).Object(objectIDs.New()) + w := obj.NewWriter(ctx) + if _, err := w.Write([]byte("abcdef")); err != nil { + return fmt.Errorf("writing object: %v", err) + } + if err := w.Close(); err != nil { + return fmt.Errorf("closing object: %v", err) + } + attrs, err := obj.Attrs(ctx) + if err != nil { + return fmt.Errorf("getting object attrs: %v", err) + } + fs.object = attrs + case storage_v1_tests.Fixture_NOTIFICATION: + // Assumes bucket has been populated first. + n, err := c.Bucket(fs.bucket.Name).AddNotification(ctx, &Notification{ + TopicProjectID: projectID, + TopicID: notificationIDs.New(), + PayloadFormat: JSONPayload, + }) + if err != nil { + return fmt.Errorf("adding notification: %v", err) + } + fs.notification = n + case storage_v1_tests.Fixture_HMAC_KEY: + key, err := c.CreateHMACKey(ctx, projectID, serviceAccountEmail) + if err != nil { + return fmt.Errorf("creating HMAC key: %v", err) + } + fs.hmacKey = key + } + return nil +} -var objName = "file.txt" +type retryFunc func(ctx context.Context, c *Client, fs *fixtures, preconditions bool) error // Methods to retry. This is a map whose keys are a string describing a standard // API call (e.g. storage.objects.get) and values are a list of functions which @@ -50,12 +114,12 @@ var objName = "file.txt" // read or just a metadata get). var methods = map[string][]retryFunc{ "storage.objects.get": { - func(ctx context.Context, c *Client, _ bool) error { - _, err := c.Bucket(bucketName).Object(objName).Attrs(ctx) + func(ctx context.Context, c *Client, fs *fixtures, _ bool) error { + _, err := c.Bucket(fs.bucket.Name).Object(fs.object.Name).Attrs(ctx) return err }, - func(ctx context.Context, c *Client, _ bool) error { - r, err := c.Bucket(bucketName).Object(objName).NewReader(ctx) + func(ctx context.Context, c *Client, fs *fixtures, _ bool) error { + r, err := c.Bucket(fs.bucket.Name).Object(fs.object.Name).NewReader(ctx) if err != nil { return err } @@ -64,22 +128,22 @@ var methods = map[string][]retryFunc{ }, }, "storage.objects.update": { - func(ctx context.Context, c *Client, preconditions bool) error { + func(ctx context.Context, c *Client, fs *fixtures, preconditions bool) error { uattrs := ObjectAttrsToUpdate{Metadata: map[string]string{"foo": "bar"}} - obj := c.Bucket(bucketName).Object(objName) + obj := c.Bucket(fs.bucket.Name).Object(fs.object.Name) if preconditions { - obj = obj.If(Conditions{MetagenerationMatch: 10}) + obj = obj.If(Conditions{MetagenerationMatch: fs.object.Metageneration}) } _, err := obj.Update(ctx, uattrs) return err }, }, "storage.buckets.update": { - func(ctx context.Context, c *Client, preconditions bool) error { + func(ctx context.Context, c *Client, fs *fixtures, preconditions bool) error { uattrs := BucketAttrsToUpdate{StorageClass: "ARCHIVE"} - bkt := c.Bucket(bucketName) + bkt := c.Bucket(fs.bucket.Name) if preconditions { - bkt = bkt.If(BucketConditions{MetagenerationMatch: 10}) + bkt = bkt.If(BucketConditions{MetagenerationMatch: fs.bucket.MetaGeneration}) } _, err := bkt.Update(ctx, uattrs) return err @@ -101,28 +165,22 @@ func TestRetryConformance(t *testing.T) { } _, _, testFiles := parseFiles(t) - for _, testFile := range(testFiles) { - for _, tc := range(testFile.RetryTests) { - for _, instructions := range(tc.Cases) { - for _, m := range(tc.Methods) { - if len(methods[m]) == 0 { - t.Logf("No tests for operation %v", m) + for _, testFile := range testFiles { + for _, tc := range testFile.RetryTests { + for _, instructions := range tc.Cases { + for _, m := range tc.Methods { + if len(methods[m.Name]) == 0 { + t.Logf("No tests for operation %v", m.Name) } - for i, f := range(methods[m]){ - testName := fmt.Sprintf("%v-%v-%v-%v", tc.Description, instructions, m, i) + for i, f := range methods[m.Name] { + testName := fmt.Sprintf("%v-%v-%v-%v", tc.Id, instructions.Instructions, m.Name, i) t.Run(testName, func(t *testing.T) { - // Setup bucket and object - // TODO: customize this by operation. - if err := client.Bucket(bucketName).Create(ctx, "myproj", &BucketAttrs{}); err != nil { - t.Errorf("Error creating bucket: %v", err) - } - w := client.Bucket(bucketName).Object(objName).NewWriter(ctx) - if _, err := w.Write([]byte("abcdef")); err != nil { - t.Errorf("Error writing object to emulator: %v", err) - } - if err := w.Close(); err != nil { - t.Errorf("Error writing object to emulator in Close: %v", err) + fs := &fixtures{} + for _, f := range m.Fixtures { + if err := fs.populate(ctx, client, f); err != nil { + t.Fatalf("creating test fixtures: %v", err) + } } // Create wrapped client which will send emulator instructions. @@ -130,7 +188,7 @@ func TestRetryConformance(t *testing.T) { if err != nil { t.Errorf("error creating wrapped client: %v", err) } - err = f(ctx, wrapped, tc.PreconditionProvided) + err = f(ctx, wrapped, fs, tc.PreconditionProvided) if tc.ExpectSuccess && err != nil { t.Errorf("want success, got %v", err) } @@ -149,8 +207,8 @@ func TestRetryConformance(t *testing.T) { } type withInstruction struct { - rt http.RoundTripper - instructions []string + rt http.RoundTripper + instructions []string } func (wi *withInstruction) RoundTrip(r *http.Request) (*http.Response, error) { diff --git a/storage/internal/test/conformance/retry_tests.json b/storage/internal/test/conformance/retry_tests.json index aef50e2234a..b4087b354a3 100644 --- a/storage/internal/test/conformance/retry_tests.json +++ b/storage/internal/test/conformance/retry_tests.json @@ -1,6 +1,7 @@ { "retryTests": [ { + "id": 1, "description": "always idempotent, retryable errors", "cases": [ { @@ -12,28 +13,16 @@ { "instructions": ["reset-connection", "return-503", "return-503"] } - ], "methods": ["storage.objects.get", "storage.buckets.get"], - "preconditionProvided": false, - "expectSuccess": true - }, - { - "description": "always idempotent, retryable errors", - "cases": [ - { - "instructions": ["return-503", "return-503", "return-503"] - }, - { - "instructions": ["reset-connection", "reset-connection", "reset-connection"] - }, - { - "instructions": ["reset-connection", "return-503", "return-503"] - } ], - "methods": ["storage.objects.get", "storage.buckets.get"], - "preconditionProvided": true, + "methods": [ + {"name": "storage.objects.get", "fixtures": ["BUCKET", "OBJECT"]}, + {"name": "storage.buckets.get", "fixtures": ["BUCKET"]} + ], + "preconditionProvided": false, "expectSuccess": true }, { + "id": 2, "description": "always idempotent, non-retryable errors", "cases": [ { @@ -47,7 +36,10 @@ "instructions": ["return-401", "return-401", "return-401"] } ], - "methods": ["storage.objects.get", "storage.buckets.get"], + "methods": [ + {"name": "storage.objects.get", "fixtures": ["BUCKET", "OBJECT"]}, + {"name": "storage.buckets.get", "fixtures": ["BUCKET"]} + ], "preconditionProvided": false, "expectSuccess": false } diff --git a/storage/internal/test/conformance/test.pb.go b/storage/internal/test/conformance/test.pb.go index 41a7f137365..6513ae221e1 100644 --- a/storage/internal/test/conformance/test.pb.go +++ b/storage/internal/test/conformance/test.pb.go @@ -49,6 +49,37 @@ func (UrlStyle) EnumDescriptor() ([]byte, []int) { return fileDescriptor_c161fcfdc0c3ff1e, []int{0} } +type Fixture int32 + +const ( + Fixture_BUCKET Fixture = 0 + Fixture_OBJECT Fixture = 1 + Fixture_NOTIFICATION Fixture = 2 + Fixture_HMAC_KEY Fixture = 3 +) + +var Fixture_name = map[int32]string{ + 0: "BUCKET", + 1: "OBJECT", + 2: "NOTIFICATION", + 3: "HMAC_KEY", +} + +var Fixture_value = map[string]int32{ + "BUCKET": 0, + "OBJECT": 1, + "NOTIFICATION": 2, + "HMAC_KEY": 3, +} + +func (x Fixture) String() string { + return proto.EnumName(Fixture_name, int32(x)) +} + +func (Fixture) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_c161fcfdc0c3ff1e, []int{1} +} + type TestFile struct { SigningV4Tests []*SigningV4Test `protobuf:"bytes,1,rep,name=signing_v4_tests,json=signingV4Tests,proto3" json:"signing_v4_tests,omitempty"` PostPolicyV4Tests []*PostPolicyV4Test `protobuf:"bytes,2,rep,name=post_policy_v4_tests,json=postPolicyV4Tests,proto3" json:"post_policy_v4_tests,omitempty"` @@ -593,12 +624,60 @@ func (m *InstructionList) GetInstructions() []string { return nil } +type Method struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Fixtures []Fixture `protobuf:"varint,2,rep,packed,name=fixtures,proto3,enum=google.cloud.conformance.storage.v1.Fixture" json:"fixtures,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Method) Reset() { *m = Method{} } +func (m *Method) String() string { return proto.CompactTextString(m) } +func (*Method) ProtoMessage() {} +func (*Method) Descriptor() ([]byte, []int) { + return fileDescriptor_c161fcfdc0c3ff1e, []int{8} +} + +func (m *Method) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Method.Unmarshal(m, b) +} +func (m *Method) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Method.Marshal(b, m, deterministic) +} +func (m *Method) XXX_Merge(src proto.Message) { + xxx_messageInfo_Method.Merge(m, src) +} +func (m *Method) XXX_Size() int { + return xxx_messageInfo_Method.Size(m) +} +func (m *Method) XXX_DiscardUnknown() { + xxx_messageInfo_Method.DiscardUnknown(m) +} + +var xxx_messageInfo_Method proto.InternalMessageInfo + +func (m *Method) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Method) GetFixtures() []Fixture { + if m != nil { + return m.Fixtures + } + return nil +} + type RetryTest struct { - Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` - Cases []*InstructionList `protobuf:"bytes,2,rep,name=cases,proto3" json:"cases,omitempty"` - Methods []string `protobuf:"bytes,3,rep,name=methods,proto3" json:"methods,omitempty"` - PreconditionProvided bool `protobuf:"varint,4,opt,name=preconditionProvided,proto3" json:"preconditionProvided,omitempty"` - ExpectSuccess bool `protobuf:"varint,5,opt,name=expectSuccess,proto3" json:"expectSuccess,omitempty"` + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + Cases []*InstructionList `protobuf:"bytes,3,rep,name=cases,proto3" json:"cases,omitempty"` + Methods []*Method `protobuf:"bytes,4,rep,name=methods,proto3" json:"methods,omitempty"` + PreconditionProvided bool `protobuf:"varint,5,opt,name=preconditionProvided,proto3" json:"preconditionProvided,omitempty"` + ExpectSuccess bool `protobuf:"varint,6,opt,name=expectSuccess,proto3" json:"expectSuccess,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -608,7 +687,7 @@ func (m *RetryTest) Reset() { *m = RetryTest{} } func (m *RetryTest) String() string { return proto.CompactTextString(m) } func (*RetryTest) ProtoMessage() {} func (*RetryTest) Descriptor() ([]byte, []int) { - return fileDescriptor_c161fcfdc0c3ff1e, []int{8} + return fileDescriptor_c161fcfdc0c3ff1e, []int{9} } func (m *RetryTest) XXX_Unmarshal(b []byte) error { @@ -629,6 +708,13 @@ func (m *RetryTest) XXX_DiscardUnknown() { var xxx_messageInfo_RetryTest proto.InternalMessageInfo +func (m *RetryTest) GetId() int32 { + if m != nil { + return m.Id + } + return 0 +} + func (m *RetryTest) GetDescription() string { if m != nil { return m.Description @@ -643,7 +729,7 @@ func (m *RetryTest) GetCases() []*InstructionList { return nil } -func (m *RetryTest) GetMethods() []string { +func (m *RetryTest) GetMethods() []*Method { if m != nil { return m.Methods } @@ -666,6 +752,7 @@ func (m *RetryTest) GetExpectSuccess() bool { func init() { proto.RegisterEnum("google.cloud.conformance.storage.v1.UrlStyle", UrlStyle_name, UrlStyle_value) + proto.RegisterEnum("google.cloud.conformance.storage.v1.Fixture", Fixture_name, Fixture_value) proto.RegisterType((*TestFile)(nil), "google.cloud.conformance.storage.v1.TestFile") proto.RegisterType((*SigningV4Test)(nil), "google.cloud.conformance.storage.v1.SigningV4Test") proto.RegisterMapType((map[string]string)(nil), "google.cloud.conformance.storage.v1.SigningV4Test.HeadersEntry") @@ -678,75 +765,82 @@ func init() { proto.RegisterMapType((map[string]string)(nil), "google.cloud.conformance.storage.v1.PolicyOutput.FieldsEntry") proto.RegisterType((*PostPolicyV4Test)(nil), "google.cloud.conformance.storage.v1.PostPolicyV4Test") proto.RegisterType((*InstructionList)(nil), "google.cloud.conformance.storage.v1.InstructionList") + proto.RegisterType((*Method)(nil), "google.cloud.conformance.storage.v1.Method") proto.RegisterType((*RetryTest)(nil), "google.cloud.conformance.storage.v1.RetryTest") } func init() { proto.RegisterFile("test.proto", fileDescriptor_c161fcfdc0c3ff1e) } var fileDescriptor_c161fcfdc0c3ff1e = []byte{ - // 1018 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xdd, 0x6e, 0xe3, 0x44, - 0x14, 0xc6, 0x49, 0xd3, 0x26, 0x27, 0xfd, 0x09, 0x43, 0x17, 0x99, 0x5c, 0x40, 0x14, 0x90, 0x28, - 0x48, 0x78, 0xb7, 0xa1, 0x95, 0x96, 0x0a, 0x84, 0xfa, 0xb7, 0xdb, 0x42, 0xb7, 0x0d, 0x93, 0xa4, - 0xab, 0x95, 0x90, 0x22, 0xd7, 0x3e, 0x49, 0xcc, 0x3a, 0x1e, 0x77, 0x66, 0x5c, 0x6d, 0xde, 0x83, - 0x17, 0xe0, 0x96, 0x97, 0xe2, 0x0a, 0x89, 0x1b, 0xde, 0x01, 0x79, 0xc6, 0x76, 0x9c, 0x6e, 0x2a, - 0x25, 0xc0, 0xde, 0x79, 0xce, 0x99, 0xf3, 0x7d, 0x33, 0x67, 0xbe, 0xf9, 0x3c, 0x00, 0x12, 0x85, - 0xb4, 0x42, 0xce, 0x24, 0x23, 0x9f, 0x0e, 0x19, 0x1b, 0xfa, 0x68, 0x39, 0x3e, 0x8b, 0x5c, 0xcb, - 0x61, 0xc1, 0x80, 0xf1, 0xb1, 0x1d, 0x38, 0x68, 0x09, 0xc9, 0xb8, 0x3d, 0x44, 0xeb, 0x6e, 0xb7, - 0xfe, 0x89, 0x9e, 0xf4, 0x58, 0x95, 0xdc, 0x44, 0x83, 0xc7, 0xd2, 0x1b, 0xa3, 0x90, 0xf6, 0x38, - 0xd4, 0x28, 0xcd, 0xdf, 0x0a, 0x50, 0xee, 0xa2, 0x90, 0xcf, 0x3c, 0x1f, 0xc9, 0xcf, 0x50, 0x13, - 0xde, 0x30, 0xf0, 0x82, 0x61, 0xff, 0x6e, 0xaf, 0x1f, 0x73, 0x09, 0xd3, 0x68, 0x14, 0x77, 0xaa, - 0xad, 0x96, 0xb5, 0x00, 0x9b, 0xd5, 0xd1, 0xc5, 0xd7, 0x7b, 0x31, 0x22, 0xdd, 0x14, 0xf9, 0xa1, - 0x20, 0x03, 0xd8, 0x0e, 0x99, 0x90, 0xfd, 0x90, 0xf9, 0x9e, 0x33, 0x99, 0x32, 0x14, 0x14, 0xc3, - 0xfe, 0x42, 0x0c, 0x6d, 0x26, 0x64, 0x5b, 0xd5, 0x27, 0x24, 0xef, 0x87, 0xf7, 0x22, 0x82, 0x5c, - 0x41, 0x95, 0xa3, 0xe4, 0x93, 0x04, 0xbe, 0xa8, 0xe0, 0xad, 0x85, 0xe0, 0x69, 0x5c, 0xa7, 0x70, - 0x81, 0xa7, 0x9f, 0xa2, 0xf9, 0xe7, 0x2a, 0x6c, 0xcc, 0x6c, 0x8d, 0xd4, 0xa1, 0x3c, 0xf0, 0x7c, - 0xbc, 0xb4, 0xc7, 0x68, 0x1a, 0x0d, 0x63, 0xa7, 0x42, 0xb3, 0x31, 0x69, 0x40, 0xd5, 0x45, 0xe1, - 0x70, 0x2f, 0x94, 0x1e, 0x0b, 0xcc, 0x82, 0x4a, 0xe7, 0x43, 0xe4, 0x43, 0x58, 0xbd, 0x89, 0x9c, - 0xd7, 0x28, 0xcd, 0xa2, 0x4a, 0x26, 0xa3, 0x38, 0xce, 0x6e, 0x7e, 0x41, 0x47, 0x9a, 0x2b, 0x3a, - 0xae, 0x47, 0x71, 0x7c, 0x8c, 0x72, 0xc4, 0x5c, 0xb3, 0xa4, 0xe3, 0x7a, 0x44, 0x3e, 0x06, 0xc0, - 0x37, 0xa1, 0xc7, 0x6d, 0x45, 0xb4, 0xda, 0x30, 0x76, 0x8a, 0x34, 0x17, 0x21, 0x4f, 0xa1, 0x92, - 0x1d, 0xb7, 0xb9, 0xd6, 0x30, 0x76, 0xaa, 0xad, 0x7a, 0xda, 0x86, 0x54, 0x10, 0x56, 0x37, 0x9d, - 0x41, 0xa7, 0x93, 0xe3, 0x3d, 0xe0, 0x9b, 0x10, 0x1d, 0x89, 0x6e, 0x8f, 0xfb, 0x66, 0x59, 0xef, - 0x21, 0x17, 0x22, 0xaf, 0x60, 0x6d, 0x84, 0xb6, 0x8b, 0x5c, 0x98, 0x15, 0xd5, 0xe0, 0xef, 0x97, - 0x57, 0x88, 0x75, 0xa6, 0x11, 0x4e, 0x03, 0xc9, 0x27, 0x34, 0xc5, 0x23, 0x1c, 0x6a, 0xb7, 0x11, - 0xf2, 0x49, 0x3f, 0xb4, 0xb9, 0x3d, 0x46, 0x19, 0x73, 0x80, 0xe2, 0x78, 0xfe, 0x2f, 0x38, 0x7e, - 0x8a, 0xa1, 0xda, 0x19, 0x92, 0xe6, 0xda, 0xba, 0x9d, 0x8d, 0xc6, 0x2d, 0x16, 0xce, 0x08, 0xc7, - 0x68, 0x56, 0x75, 0x8b, 0xf5, 0x88, 0x9c, 0x43, 0x39, 0xe2, 0x7e, 0x47, 0x4e, 0x7c, 0x34, 0xd7, - 0x1b, 0xc6, 0xce, 0x66, 0xeb, 0xab, 0x85, 0xd6, 0xd0, 0x4b, 0x8a, 0x68, 0x56, 0x4e, 0x9e, 0xc0, - 0x07, 0xfa, 0x9c, 0x8f, 0x58, 0x14, 0xb8, 0x67, 0x4c, 0xc8, 0x20, 0x96, 0xcf, 0x86, 0xe2, 0x9b, - 0x97, 0x22, 0x07, 0x60, 0xa6, 0x2d, 0x3f, 0xb6, 0x03, 0x16, 0x78, 0x8e, 0xed, 0x53, 0xbc, 0x8d, - 0x50, 0x48, 0x73, 0x53, 0x95, 0x3d, 0x98, 0x27, 0x2d, 0xd8, 0x4e, 0x73, 0x1d, 0xc9, 0xbd, 0x60, - 0xd8, 0x65, 0x71, 0x5f, 0xcc, 0x2d, 0x55, 0x37, 0x37, 0x57, 0x3f, 0x80, 0xf5, 0xfc, 0x89, 0x90, - 0x1a, 0x14, 0x5f, 0xe3, 0x24, 0x11, 0x78, 0xfc, 0x49, 0xb6, 0xa1, 0x74, 0x67, 0xfb, 0x11, 0x26, - 0xaa, 0xd6, 0x83, 0x83, 0xc2, 0x53, 0xa3, 0x7e, 0x04, 0xdb, 0xf3, 0x3a, 0xbd, 0x0c, 0x46, 0x73, - 0x0f, 0xc8, 0x31, 0x0b, 0x5c, 0x2f, 0x16, 0xaf, 0xed, 0xbf, 0xb0, 0xa5, 0x33, 0x42, 0x91, 0xa8, - 0x9c, 0xa3, 0x10, 0xb1, 0xca, 0x63, 0x3b, 0xaa, 0xd0, 0x5c, 0xa4, 0x79, 0x03, 0x35, 0x7d, 0xff, - 0xb3, 0x5a, 0x41, 0x2c, 0x20, 0x0e, 0x0b, 0x24, 0x06, 0xf2, 0x02, 0x83, 0xa1, 0x1c, 0x51, 0x3b, - 0x18, 0xa2, 0xaa, 0x2d, 0xd1, 0x39, 0x99, 0x98, 0x43, 0x48, 0x9b, 0x4b, 0xf1, 0xd2, 0x93, 0x23, - 0x65, 0x48, 0x15, 0x9a, 0x8b, 0x34, 0x7f, 0x5d, 0x81, 0xaa, 0x26, 0x39, 0x0f, 0xc2, 0x48, 0xe6, - 0xe4, 0x62, 0x3c, 0x28, 0x97, 0xc2, 0x3b, 0x91, 0x4b, 0xf1, 0x61, 0xb9, 0x4c, 0x6d, 0x65, 0xe5, - 0x01, 0x5b, 0x29, 0xcd, 0xd8, 0xca, 0xdb, 0xf6, 0x51, 0xfa, 0x9f, 0xec, 0xa3, 0x0b, 0xab, 0x03, - 0x0f, 0x7d, 0x57, 0x98, 0x65, 0x75, 0x6f, 0xbf, 0x5d, 0xd0, 0xdb, 0xb3, 0x06, 0x5b, 0xcf, 0x54, - 0xb9, 0xbe, 0xac, 0x09, 0x16, 0xe9, 0x01, 0x38, 0xd9, 0x11, 0x9b, 0x15, 0xb5, 0xa0, 0xfd, 0x25, - 0x90, 0xa7, 0xfa, 0xa0, 0x39, 0xa0, 0xfa, 0x37, 0x50, 0xcd, 0xb1, 0x2d, 0x25, 0xd8, 0xbf, 0x0c, - 0x58, 0xd7, 0xd8, 0x57, 0x91, 0x8c, 0x75, 0x51, 0x83, 0x62, 0xc4, 0xfd, 0xb4, 0x38, 0xe2, 0x3e, - 0xe9, 0x65, 0xad, 0xd0, 0xbf, 0xb9, 0xef, 0x96, 0x58, 0xb0, 0x06, 0x9d, 0xdb, 0x8b, 0x3d, 0x78, - 0x94, 0x5e, 0xe1, 0x13, 0x74, 0x98, 0x8b, 0xae, 0x2e, 0x49, 0xf4, 0x31, 0x3f, 0xf9, 0x5f, 0xb6, - 0xfa, 0x87, 0x11, 0x5f, 0xb3, 0xd9, 0x5f, 0xed, 0xfd, 0x5f, 0x9d, 0xf1, 0xf6, 0xaf, 0x8e, 0x42, - 0x35, 0x9c, 0x1e, 0xab, 0x82, 0xad, 0xb6, 0x9e, 0x2c, 0x2b, 0x07, 0x9a, 0x07, 0x21, 0x3d, 0x58, - 0x0f, 0x73, 0xfd, 0x51, 0x5b, 0xae, 0xb6, 0x76, 0x97, 0x6e, 0x2c, 0x9d, 0x81, 0x69, 0xee, 0xc3, - 0xd6, 0x79, 0x20, 0x24, 0x8f, 0x9c, 0x78, 0xe5, 0x17, 0x9e, 0x90, 0xa4, 0x09, 0xeb, 0xde, 0x34, - 0x24, 0x12, 0xf3, 0x99, 0x89, 0x35, 0xff, 0x36, 0xa0, 0x92, 0x3d, 0x1b, 0x16, 0xe8, 0xc8, 0x0f, - 0x50, 0x72, 0x6c, 0x81, 0xa9, 0x1e, 0xf6, 0x16, 0x5a, 0xf6, 0xbd, 0x85, 0x51, 0x0d, 0x41, 0x4c, - 0x58, 0xd3, 0x4f, 0x01, 0xfd, 0xca, 0xa9, 0xd0, 0x74, 0x18, 0xdb, 0x7f, 0xc8, 0x31, 0x53, 0x79, - 0x9b, 0xb3, 0x3b, 0xcf, 0x45, 0x57, 0x39, 0x43, 0x99, 0xce, 0xcd, 0x91, 0xcf, 0x60, 0x43, 0xcb, - 0xa6, 0x13, 0x39, 0x0e, 0x0a, 0xa1, 0xec, 0xa2, 0x4c, 0x67, 0x83, 0x5f, 0x5e, 0x41, 0x39, 0x75, - 0x2b, 0xb2, 0x09, 0xd0, 0x3e, 0xec, 0x9e, 0xf5, 0x3b, 0xdd, 0x57, 0x17, 0xa7, 0xb5, 0xf7, 0x88, - 0x09, 0xdb, 0xd7, 0xe7, 0xb4, 0xdb, 0x3b, 0xbc, 0xe8, 0x9f, 0x5d, 0x75, 0xba, 0xa7, 0x27, 0x49, - 0xc6, 0x20, 0x1f, 0xc1, 0xa3, 0xa3, 0xde, 0xf1, 0x8f, 0xa7, 0xdd, 0xfe, 0xd1, 0x55, 0xef, 0xf2, - 0x44, 0xa5, 0x2f, 0x0f, 0x5f, 0x9c, 0xd6, 0x0a, 0x47, 0x2f, 0xe1, 0x73, 0x87, 0x8d, 0x17, 0x69, - 0x43, 0xdb, 0xf8, 0xbd, 0xf0, 0xc5, 0x73, 0x3d, 0xef, 0x58, 0xcd, 0xeb, 0x24, 0xb9, 0xeb, 0x5d, - 0x4b, 0x3d, 0xd5, 0xac, 0xe3, 0x69, 0xe1, 0xcd, 0xaa, 0x32, 0xa9, 0xaf, 0xff, 0x09, 0x00, 0x00, - 0xff, 0xff, 0x5e, 0x7a, 0x44, 0x3f, 0x35, 0x0b, 0x00, 0x00, + // 1120 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xdf, 0x8e, 0xda, 0xc6, + 0x17, 0x8e, 0x61, 0x61, 0xe1, 0x40, 0x88, 0x7f, 0xf3, 0xdb, 0x54, 0x2e, 0x17, 0x2d, 0xa2, 0x95, + 0xba, 0x4d, 0x5b, 0x27, 0xa1, 0x1b, 0x29, 0x8d, 0x5a, 0x55, 0x40, 0xd8, 0x40, 0xb2, 0xbb, 0x50, + 0x63, 0x36, 0x5a, 0xa9, 0x12, 0xf2, 0xda, 0x03, 0xb8, 0x31, 0x1e, 0xef, 0xcc, 0x78, 0xb5, 0xbc, + 0x47, 0x5f, 0xa0, 0xb7, 0x79, 0xa9, 0x5e, 0x55, 0xea, 0x63, 0x54, 0x9e, 0xb1, 0xc1, 0x6c, 0x58, + 0x09, 0xfa, 0xe7, 0x6e, 0xe6, 0x9c, 0xf9, 0xbe, 0x33, 0x73, 0xe6, 0x9b, 0x33, 0x07, 0x80, 0x63, + 0xc6, 0xf5, 0x80, 0x12, 0x4e, 0xd0, 0x67, 0x53, 0x42, 0xa6, 0x1e, 0xd6, 0x6d, 0x8f, 0x84, 0x8e, + 0x6e, 0x13, 0x7f, 0x42, 0xe8, 0xdc, 0xf2, 0x6d, 0xac, 0x33, 0x4e, 0xa8, 0x35, 0xc5, 0xfa, 0xf5, + 0xd3, 0xea, 0xa7, 0x72, 0xd1, 0x63, 0x01, 0xb9, 0x0c, 0x27, 0x8f, 0xb9, 0x3b, 0xc7, 0x8c, 0x5b, + 0xf3, 0x40, 0xb2, 0xd4, 0x7f, 0xcb, 0x40, 0xc1, 0xc4, 0x8c, 0x1f, 0xbb, 0x1e, 0x46, 0x3f, 0x83, + 0xca, 0xdc, 0xa9, 0xef, 0xfa, 0xd3, 0xf1, 0xf5, 0xd1, 0x38, 0x8a, 0xc5, 0x34, 0xa5, 0x96, 0x3d, + 0x2c, 0x35, 0x1a, 0xfa, 0x16, 0xd1, 0xf4, 0xa1, 0x04, 0x9f, 0x1f, 0x45, 0x8c, 0x46, 0x85, 0xa5, + 0xa7, 0x0c, 0x4d, 0xe0, 0x20, 0x20, 0x8c, 0x8f, 0x03, 0xe2, 0xb9, 0xf6, 0x62, 0x15, 0x21, 0x23, + 0x22, 0x3c, 0xdb, 0x2a, 0xc2, 0x80, 0x30, 0x3e, 0x10, 0xf8, 0x38, 0xc8, 0xff, 0x82, 0x5b, 0x16, + 0x86, 0xfa, 0x50, 0xa2, 0x98, 0xd3, 0x45, 0x4c, 0x9f, 0x15, 0xf4, 0xfa, 0x56, 0xf4, 0x46, 0x84, + 0x13, 0xbc, 0x40, 0x93, 0x21, 0xab, 0xff, 0x91, 0x87, 0xfb, 0x6b, 0x47, 0x43, 0x55, 0x28, 0x4c, + 0x5c, 0x0f, 0x9f, 0x59, 0x73, 0xac, 0x29, 0x35, 0xe5, 0xb0, 0x68, 0x2c, 0xe7, 0xa8, 0x06, 0x25, + 0x07, 0x33, 0x9b, 0xba, 0x01, 0x77, 0x89, 0xaf, 0x65, 0x84, 0x3b, 0x6d, 0x42, 0x1f, 0x41, 0xfe, + 0x32, 0xb4, 0xdf, 0x61, 0xae, 0x65, 0x85, 0x33, 0x9e, 0x45, 0x76, 0x72, 0xf9, 0x0b, 0xb6, 0xb9, + 0xb6, 0x27, 0xed, 0x72, 0x16, 0xd9, 0xe7, 0x98, 0xcf, 0x88, 0xa3, 0xe5, 0xa4, 0x5d, 0xce, 0xd0, + 0x27, 0x00, 0xf8, 0x26, 0x70, 0xa9, 0x25, 0x02, 0xe5, 0x6b, 0xca, 0x61, 0xd6, 0x48, 0x59, 0xd0, + 0x73, 0x28, 0x2e, 0xaf, 0x5b, 0xdb, 0xaf, 0x29, 0x87, 0xa5, 0x46, 0x35, 0x49, 0x43, 0x22, 0x08, + 0xdd, 0x4c, 0x56, 0x18, 0xab, 0xc5, 0xd1, 0x19, 0xf0, 0x4d, 0x80, 0x6d, 0x8e, 0x9d, 0x11, 0xf5, + 0xb4, 0x82, 0x3c, 0x43, 0xca, 0x84, 0x2e, 0x60, 0x7f, 0x86, 0x2d, 0x07, 0x53, 0xa6, 0x15, 0x45, + 0x82, 0x7f, 0xdc, 0x5d, 0x21, 0x7a, 0x57, 0x32, 0x74, 0x7c, 0x4e, 0x17, 0x46, 0xc2, 0x87, 0x28, + 0xa8, 0x57, 0x21, 0xa6, 0x8b, 0x71, 0x60, 0x51, 0x6b, 0x8e, 0x79, 0x14, 0x03, 0x44, 0x8c, 0x57, + 0x7f, 0x23, 0xc6, 0x4f, 0x11, 0xd5, 0x60, 0xc9, 0x24, 0x63, 0x3d, 0xb8, 0x5a, 0xb7, 0x46, 0x29, + 0x66, 0xf6, 0x0c, 0xcf, 0xb1, 0x56, 0x92, 0x29, 0x96, 0x33, 0xd4, 0x83, 0x42, 0x48, 0xbd, 0x21, + 0x5f, 0x78, 0x58, 0x2b, 0xd7, 0x94, 0xc3, 0x4a, 0xe3, 0x9b, 0xad, 0xf6, 0x30, 0x8a, 0x41, 0xc6, + 0x12, 0x8e, 0x9e, 0xc0, 0xff, 0xe5, 0x3d, 0xb7, 0x48, 0xe8, 0x3b, 0x5d, 0xc2, 0xb8, 0x1f, 0xc9, + 0xe7, 0xbe, 0x88, 0xb7, 0xc9, 0x85, 0x5e, 0x80, 0x96, 0xa4, 0xbc, 0x6d, 0xf9, 0xc4, 0x77, 0x6d, + 0xcb, 0x33, 0xf0, 0x55, 0x88, 0x19, 0xd7, 0x2a, 0x02, 0x76, 0xa7, 0x1f, 0x35, 0xe0, 0x20, 0xf1, + 0x0d, 0x39, 0x75, 0xfd, 0xa9, 0x49, 0xa2, 0xbc, 0x68, 0x0f, 0x04, 0x6e, 0xa3, 0xaf, 0xfa, 0x02, + 0xca, 0xe9, 0x1b, 0x41, 0x2a, 0x64, 0xdf, 0xe1, 0x45, 0x2c, 0xf0, 0x68, 0x88, 0x0e, 0x20, 0x77, + 0x6d, 0x79, 0x21, 0x8e, 0x55, 0x2d, 0x27, 0x2f, 0x32, 0xcf, 0x95, 0x6a, 0x0b, 0x0e, 0x36, 0x65, + 0x7a, 0x17, 0x8e, 0xfa, 0x11, 0xa0, 0x36, 0xf1, 0x1d, 0x37, 0x12, 0xaf, 0xe5, 0x9d, 0x5a, 0xdc, + 0x9e, 0x61, 0x16, 0xab, 0x9c, 0x62, 0xc6, 0x22, 0x95, 0x47, 0xe5, 0xa8, 0x68, 0xa4, 0x2c, 0xf5, + 0x4b, 0x50, 0xe5, 0xfb, 0x5f, 0x62, 0x19, 0xd2, 0x01, 0xd9, 0xc4, 0xe7, 0xd8, 0xe7, 0x27, 0xd8, + 0x9f, 0xf2, 0x99, 0x61, 0xf9, 0x53, 0x2c, 0xb0, 0x39, 0x63, 0x83, 0x27, 0x8a, 0xc1, 0xb8, 0x45, + 0x39, 0x7b, 0xeb, 0xf2, 0x99, 0x28, 0x48, 0x45, 0x23, 0x65, 0xa9, 0xff, 0xba, 0x07, 0x25, 0x19, + 0xa4, 0xe7, 0x07, 0x21, 0x4f, 0xc9, 0x45, 0xb9, 0x53, 0x2e, 0x99, 0xff, 0x44, 0x2e, 0xd9, 0xbb, + 0xe5, 0xb2, 0x2a, 0x2b, 0x7b, 0x77, 0x94, 0x95, 0xdc, 0x5a, 0x59, 0xf9, 0xb0, 0x7c, 0xe4, 0xfe, + 0xa5, 0xf2, 0x61, 0x42, 0x7e, 0xe2, 0x62, 0xcf, 0x61, 0x5a, 0x41, 0xbc, 0xdb, 0xef, 0xb7, 0xac, + 0xed, 0xcb, 0x04, 0xeb, 0xc7, 0x02, 0x2e, 0x1f, 0x6b, 0xcc, 0x85, 0x46, 0x00, 0xf6, 0xf2, 0x8a, + 0xb5, 0xa2, 0xd8, 0xd0, 0xb3, 0x1d, 0x98, 0x57, 0xfa, 0x30, 0x52, 0x44, 0xd5, 0xef, 0xa0, 0x94, + 0x8a, 0xb6, 0x93, 0x60, 0xff, 0x54, 0xa0, 0x2c, 0xb9, 0xfb, 0x21, 0x8f, 0x74, 0xa1, 0x42, 0x36, + 0xa4, 0x5e, 0x02, 0x0e, 0xa9, 0x87, 0x46, 0xcb, 0x54, 0xc8, 0x6f, 0xee, 0x87, 0x1d, 0x36, 0x2c, + 0x49, 0x37, 0xe6, 0xe2, 0x08, 0x1e, 0x26, 0x4f, 0xf8, 0x25, 0xb6, 0x89, 0x83, 0x1d, 0x09, 0x89, + 0xf5, 0xb1, 0xd9, 0xf9, 0x4f, 0x8e, 0xfa, 0xbb, 0x12, 0x3d, 0xb3, 0xf5, 0xaf, 0xf6, 0xf6, 0x57, + 0xa7, 0x7c, 0xf8, 0xd5, 0x19, 0x50, 0x0a, 0x56, 0xd7, 0x2a, 0x68, 0x4b, 0x8d, 0x27, 0xbb, 0xca, + 0xc1, 0x48, 0x93, 0xa0, 0x11, 0x94, 0x83, 0x54, 0x7e, 0xc4, 0x91, 0x4b, 0x8d, 0xa7, 0x3b, 0x27, + 0xd6, 0x58, 0xa3, 0xa9, 0x3f, 0x83, 0x07, 0x3d, 0x9f, 0x71, 0x1a, 0xda, 0xd1, 0xce, 0x4f, 0x5c, + 0xc6, 0x51, 0x1d, 0xca, 0xee, 0xca, 0xc4, 0xe2, 0xe2, 0xb3, 0x66, 0xab, 0x4f, 0x20, 0x7f, 0x2a, + 0xbf, 0x63, 0x04, 0x7b, 0xfe, 0xaa, 0x21, 0x10, 0x63, 0xd4, 0x8d, 0x1a, 0x85, 0x1b, 0x1e, 0x52, + 0x2c, 0x05, 0x50, 0x69, 0x7c, 0xbd, 0xd5, 0x3e, 0x8f, 0x25, 0xc8, 0x58, 0xa2, 0xeb, 0xef, 0x33, + 0x50, 0x5c, 0xb6, 0x27, 0xa8, 0x02, 0x19, 0xd7, 0x11, 0x91, 0x72, 0x46, 0xc6, 0x75, 0xb6, 0x68, + 0x3a, 0x5e, 0x43, 0xce, 0xb6, 0x18, 0x4e, 0xfa, 0xa1, 0xa3, 0xad, 0xb6, 0x71, 0x2b, 0x21, 0x86, + 0xa4, 0x40, 0x1d, 0xd8, 0x97, 0x2d, 0x08, 0xd3, 0xf6, 0x04, 0xdb, 0x57, 0x5b, 0xb1, 0xc9, 0x3c, + 0x19, 0x09, 0x36, 0xfa, 0xa3, 0x02, 0x8a, 0x97, 0x4f, 0x71, 0x40, 0xc9, 0xb5, 0xeb, 0x60, 0xd9, + 0xe5, 0x14, 0x8c, 0x8d, 0x3e, 0xf4, 0x39, 0xdc, 0x97, 0xda, 0x1e, 0x86, 0xb6, 0x8d, 0x19, 0x13, + 0x75, 0xab, 0x60, 0xac, 0x1b, 0x1f, 0xf5, 0xa1, 0x90, 0x94, 0x54, 0x54, 0x01, 0x18, 0x34, 0xcd, + 0xee, 0x78, 0x68, 0x5e, 0x9c, 0x74, 0xd4, 0x7b, 0x48, 0x83, 0x83, 0xf3, 0x9e, 0x61, 0x8e, 0x9a, + 0x27, 0xe3, 0x6e, 0x7f, 0x68, 0x76, 0x5e, 0xc6, 0x1e, 0x05, 0x7d, 0x0c, 0x0f, 0x5b, 0xa3, 0xf6, + 0x9b, 0x8e, 0x39, 0x6e, 0xf5, 0x47, 0x67, 0x2f, 0x85, 0xfb, 0xac, 0x79, 0xda, 0x51, 0x33, 0x8f, + 0x9a, 0xb0, 0x1f, 0x5f, 0x09, 0x02, 0xc8, 0xcb, 0x55, 0xea, 0xbd, 0x68, 0xdc, 0x6f, 0xbd, 0xee, + 0xb4, 0x4d, 0x55, 0x41, 0x2a, 0x94, 0xcf, 0xfa, 0x66, 0xef, 0xb8, 0xd7, 0x6e, 0x9a, 0xbd, 0xfe, + 0x99, 0x9a, 0x41, 0x65, 0x28, 0x74, 0x4f, 0x9b, 0xed, 0xf1, 0x9b, 0xce, 0x85, 0x9a, 0x6d, 0xbd, + 0x85, 0x2f, 0x6c, 0x32, 0xdf, 0x26, 0x51, 0x03, 0xe5, 0x7d, 0xe6, 0xcb, 0x57, 0x72, 0x5d, 0x5b, + 0xac, 0x1b, 0xc6, 0xbe, 0xf3, 0xa7, 0xba, 0x68, 0x49, 0xf5, 0xf6, 0x0a, 0x78, 0x99, 0x17, 0xc5, + 0xf8, 0xdb, 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0x13, 0x63, 0x45, 0x57, 0x1d, 0x0c, 0x00, 0x00, } diff --git a/storage/internal/test/conformance/test.proto b/storage/internal/test/conformance/test.proto index abcaa5115e6..7062ef88ab4 100644 --- a/storage/internal/test/conformance/test.proto +++ b/storage/internal/test/conformance/test.proto @@ -89,11 +89,22 @@ message InstructionList { repeated string instructions = 1; // e.g. return-503 } +enum Fixture { + BUCKET = 0; + OBJECT = 1; + NOTIFICATION = 2; + HMAC_KEY = 3; +} +message Method { + string name = 1; + repeated Fixture fixtures = 2; +} + message RetryTest { - string description = 1; - repeated InstructionList cases = 2; - repeated string methods = 3; // e.g. storage.objects.get - bool preconditionProvided = 4; - bool expectSuccess = 5; - // repeated string setup = 6; // List of setup steps required for the test. (e.g. bucket created, object created, etc) + int32 id = 1; + string description = 2; + repeated InstructionList cases = 3; + repeated Method methods = 4; // e.g. storage.objects.get + bool preconditionProvided = 5; + bool expectSuccess = 6; } From 57cc43e8ce80bcd9937d6171c3dd3215ebbe45a7 Mon Sep 17 00:00:00 2001 From: Chris Cotter Date: Fri, 2 Apr 2021 15:29:34 -0400 Subject: [PATCH 08/25] update schema with comments --- storage/internal/test/conformance/test.proto | 31 ++++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/storage/internal/test/conformance/test.proto b/storage/internal/test/conformance/test.proto index 7062ef88ab4..d76ec856cad 100644 --- a/storage/internal/test/conformance/test.proto +++ b/storage/internal/test/conformance/test.proto @@ -85,26 +85,51 @@ message PostPolicyV4Test { PolicyOutput policyOutput = 3; } +/* +Data types for retry conformance tests. +*/ + +// A list of instructions to send as headers to the GCS emulator. Each +// instruction will force a specified failure for that request. message InstructionList { - repeated string instructions = 1; // e.g. return-503 + repeated string instructions = 1; } +// Test fixtures that are necessary for a method call. For example, +// storage.objects.get would require BUCKET and OBJECT. enum Fixture { BUCKET = 0; OBJECT = 1; NOTIFICATION = 2; HMAC_KEY = 3; } + +// A particular storage API method and required fixtures in order to test it. +// Methods must be implemented in tests for each language. message Method { - string name = 1; + string name = 1; // e.g. storage.objects.get repeated Fixture fixtures = 2; } +// Schema for a retry test, corresponding to a single scenario from the design +// doc. message RetryTest { int32 id = 1; + + // Human-readable description of the test case. string description = 2; + + // List of emulator instructions. repeated InstructionList cases = 3; - repeated Method methods = 4; // e.g. storage.objects.get + + // List of API methods to be tested. + repeated Method methods = 4; + + // Whether a precondition is provided (for conditionally-idempotent methods + // only). bool preconditionProvided = 5; + + // Whether we expect the method calls to eventually succeed after the client + // library retries. bool expectSuccess = 6; } From c6385cde9dbb49c32247802859687858d3a3ac08 Mon Sep 17 00:00:00 2001 From: Chris Cotter Date: Fri, 2 Apr 2021 15:39:26 -0400 Subject: [PATCH 09/25] update test cases --- .../test/conformance/retry_tests.json | 66 ++++++++++++++++--- 1 file changed, 56 insertions(+), 10 deletions(-) diff --git a/storage/internal/test/conformance/retry_tests.json b/storage/internal/test/conformance/retry_tests.json index b4087b354a3..f9d72fcab18 100644 --- a/storage/internal/test/conformance/retry_tests.json +++ b/storage/internal/test/conformance/retry_tests.json @@ -2,7 +2,7 @@ "retryTests": [ { "id": 1, - "description": "always idempotent, retryable errors", + "description": "always idempotent", "cases": [ { "instructions": ["return-503", "return-503", "return-503"] @@ -15,22 +15,64 @@ } ], "methods": [ - {"name": "storage.objects.get", "fixtures": ["BUCKET", "OBJECT"]}, - {"name": "storage.buckets.get", "fixtures": ["BUCKET"]} + {"name": "storage.buckets.get", "fixtures": ["BUCKET"]}, + {"name": "storage.objects.get", "fixtures": ["BUCKET", "OBJECT"]} ], "preconditionProvided": false, "expectSuccess": true }, { "id": 2, - "description": "always idempotent, non-retryable errors", + "description": "conditionally idempotent, precondition present", + "cases": [ + { + "instructions": ["return-503", "return-503", "return-503"] + }, + { + "instructions": ["reset-connection", "reset-connection", "reset-connection"] + }, + { + "instructions": ["reset-connection", "return-503", "return-503"] + } + ], + "methods": [ + {"name": "storage.buckets.insert", "fixtures": []}, + {"name": "storage.buckets.update", "fixtures": ["BUCKET"]}, + {"name": "storage.objects.insert", "fixtures": ["BUCKET"]}, + {"name": "storage.objects.update", "fixtures": ["BUCKET", "OBJECT"]} + ], + "preconditionProvided": true, + "expectSuccess": true + }, + { + "id": 2, + "description": "conditionally idempotent, precondition not present", + "cases": [ + { + "instructions": ["return-503", "return-503", "return-503"] + }, + { + "instructions": ["reset-connection", "reset-connection", "reset-connection"] + }, + { + "instructions": ["reset-connection", "return-503", "return-503"] + } + ], + "methods": [ + {"name": "storage.buckets.insert", "fixtures": []}, + {"name": "storage.buckets.update", "fixtures": ["BUCKET"]}, + {"name": "storage.objects.insert", "fixtures": ["BUCKET"]}, + {"name": "storage.objects.update", "fixtures": ["BUCKET", "OBJECT"]} + ], + "preconditionProvided": false, + "expectSuccess": false + }, + { + "id": 6, + "description": "non-retryable errors", "cases": [ { - "instructions": [ - "return-400", - "return-400", - "return-400" - ] + "instructions": ["return-400", "return-400", "return-400"] }, { "instructions": ["return-401", "return-401", "return-401"] @@ -38,7 +80,11 @@ ], "methods": [ {"name": "storage.objects.get", "fixtures": ["BUCKET", "OBJECT"]}, - {"name": "storage.buckets.get", "fixtures": ["BUCKET"]} + {"name": "storage.buckets.get", "fixtures": ["BUCKET"]}, + {"name": "storage.buckets.insert", "fixtures": []}, + {"name": "storage.buckets.update", "fixtures": ["BUCKET"]}, + {"name": "storage.objects.insert", "fixtures": ["BUCKET"]}, + {"name": "storage.objects.update", "fixtures": ["BUCKET", "OBJECT"]} ], "preconditionProvided": false, "expectSuccess": false From 14c25b6eb388fbe0a8358311d83a36b483009625 Mon Sep 17 00:00:00 2001 From: Chris Cotter Date: Fri, 2 Apr 2021 17:51:00 -0400 Subject: [PATCH 10/25] fix id --- storage/internal/test/conformance/retry_tests.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/internal/test/conformance/retry_tests.json b/storage/internal/test/conformance/retry_tests.json index f9d72fcab18..d635e9edfce 100644 --- a/storage/internal/test/conformance/retry_tests.json +++ b/storage/internal/test/conformance/retry_tests.json @@ -45,7 +45,7 @@ "expectSuccess": true }, { - "id": 2, + "id": 3, "description": "conditionally idempotent, precondition not present", "cases": [ { From 5ddf761878a616b504878f7a2e250c4fde2c6f8f Mon Sep 17 00:00:00 2001 From: Chris Cotter Date: Fri, 16 Apr 2021 15:30:21 -0400 Subject: [PATCH 11/25] change to new emu format [WIP] --- storage/conformance_test.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/storage/conformance_test.go b/storage/conformance_test.go index 9a1e0da50d4..7563a1e8917 100644 --- a/storage/conformance_test.go +++ b/storage/conformance_test.go @@ -44,6 +44,7 @@ var ( bucketIDs = uid.NewSpace("bucket", nil) objectIDs = uid.NewSpace("object", nil) notificationIDs = uid.NewSpace("notification", nil) + testIDs = uid.NewSpace("test", nil) projectID = "my-project-id" serviceAccountEmail = "my-sevice-account@my-project-id.iam.gserviceaccount.com" ) @@ -150,6 +151,11 @@ var methods = map[string][]retryFunc{ }}, } +type payload struct { + id string + instructions []string +} + func TestRetryConformance(t *testing.T) { if os.Getenv("STORAGE_EMULATOR_HOST") == "" { @@ -183,6 +189,20 @@ func TestRetryConformance(t *testing.T) { } } + host := os.Getenv("STORAGE_EMULATOR_HOST") + endpoint := host + "/setup_retry_test" + c := http.DefaultClient + + p := payload{ + id: testIDs.New(), + instructions: instructions.Instructions, + } + body := bytes.NewBuffer(json.Marshal(p)) + r, err := c.Post(endpoint, "application/json", body) + if err != nil { + + } + // Create wrapped client which will send emulator instructions. wrapped, err := wrappedClient(instructions.Instructions) if err != nil { From 4b1b2b9ece340b7a46d66166b2638fd3e8ff9f72 Mon Sep 17 00:00:00 2001 From: Chris Cotter Date: Mon, 3 May 2021 14:47:53 -0400 Subject: [PATCH 12/25] use new retry_test resource --- storage/conformance_test.go | 107 ++++++++++++++++++++++++------------ 1 file changed, 72 insertions(+), 35 deletions(-) diff --git a/storage/conformance_test.go b/storage/conformance_test.go index 7563a1e8917..57ccabd99b2 100644 --- a/storage/conformance_test.go +++ b/storage/conformance_test.go @@ -22,7 +22,6 @@ import ( "fmt" "io" "io/ioutil" - "log" "net/http" "net/url" "os" @@ -44,7 +43,6 @@ var ( bucketIDs = uid.NewSpace("bucket", nil) objectIDs = uid.NewSpace("object", nil) notificationIDs = uid.NewSpace("notification", nil) - testIDs = uid.NewSpace("test", nil) projectID = "my-project-id" serviceAccountEmail = "my-sevice-account@my-project-id.iam.gserviceaccount.com" ) @@ -151,21 +149,17 @@ var methods = map[string][]retryFunc{ }}, } -type payload struct { - id string - instructions []string -} func TestRetryConformance(t *testing.T) { - - if os.Getenv("STORAGE_EMULATOR_HOST") == "" { + host := os.Getenv("STORAGE_EMULATOR_HOST") + if host == "" { t.Skip("This test must use the testbench emulator; set STORAGE_EMULATOR_HOST to run.") } ctx := context.Background() // Create non-wrapped client to use for setup steps. - client, err := NewClient(ctx) + client, err := NewClient(ctx, option.WithEndpoint("http://localhost:9000/storage/v1/")) if err != nil { t.Fatalf("storage.NewClient: %v", err) } @@ -182,6 +176,22 @@ func TestRetryConformance(t *testing.T) { testName := fmt.Sprintf("%v-%v-%v-%v", tc.Id, instructions.Instructions, m.Name, i) t.Run(testName, func(t *testing.T) { + // Create the retry test in the emulator to handle instructions. + testID, err := createRetryTest(host, map[string][]string{ + m.Name: instructions.Instructions, + }) + if err != nil { + t.Fatalf("setting up retry test: %v", err) + } + + defer func() { + // Close out test in emulator and verify that all instructions + // were used. + if err := deleteRetryTest(host, testID); err != nil { + t.Errorf("deleting retry test: %v", err) + } + }() + fs := &fixtures{} for _, f := range m.Fixtures { if err := fs.populate(ctx, client, f); err != nil { @@ -189,22 +199,8 @@ func TestRetryConformance(t *testing.T) { } } - host := os.Getenv("STORAGE_EMULATOR_HOST") - endpoint := host + "/setup_retry_test" - c := http.DefaultClient - - p := payload{ - id: testIDs.New(), - instructions: instructions.Instructions, - } - body := bytes.NewBuffer(json.Marshal(p)) - r, err := c.Post(endpoint, "application/json", body) - if err != nil { - - } - // Create wrapped client which will send emulator instructions. - wrapped, err := wrappedClient(instructions.Instructions) + wrapped, err := wrappedClient(testID) if err != nil { t.Errorf("error creating wrapped client: %v", err) } @@ -216,6 +212,7 @@ func TestRetryConformance(t *testing.T) { t.Errorf("want failure, got success") } + }) } @@ -226,18 +223,58 @@ func TestRetryConformance(t *testing.T) { } -type withInstruction struct { - rt http.RoundTripper - instructions []string +func createRetryTest(host string, instructions map[string][]string) (string, error) { + endpoint := "http://" + host + "/retry_test" + c := http.DefaultClient + data := struct{ + Instructions map[string][]string `json:"test_instructions"` + }{ + Instructions: instructions, + } + + buf := new(bytes.Buffer) + if err := json.NewEncoder(buf).Encode(data); err != nil { + return "", fmt.Errorf("encoding request: %v", err) + } + res, err := c.Post(endpoint, "application/json", buf) + if err != nil { + return "", fmt.Errorf("creating retry test: %v", err) + } + defer res.Body.Close() + testRes := struct{ + TestID string `json:"id"` + }{} + if err := json.NewDecoder(res.Body).Decode(&testRes); err != nil { + return "", fmt.Errorf("decoding test ID: %v", err) + } + return testRes.TestID, nil } -func (wi *withInstruction) RoundTrip(r *http.Request) (*http.Response, error) { - if len(wi.instructions) > 0 { - r.Header.Set("x-goog-testbench-instructions", wi.instructions[0]) - wi.instructions = wi.instructions[1:] +func deleteRetryTest(host, testID string) error { + endpoint := "http://" + strings.Join([]string{host, "retry_test", testID}, "/") + c := http.DefaultClient + req, err := http.NewRequest("DELETE", endpoint, nil) + if err != nil { + return fmt.Errorf("creating request: %v", err) + } + resp, err := c.Do(req) + if err != nil { + return fmt.Errorf("deleting test: %v", err) } - log.Printf("Request: %+v\nRemaining instructions: %v\n\n", r, wi.instructions) - resp, err := wi.rt.RoundTrip(r) + if resp.StatusCode != 200 { + return fmt.Errorf("delete test failed, response: %+v", resp) + } + return nil +} + +type withTestID struct { + rt http.RoundTripper + testID string +} + +func (wt *withTestID) RoundTrip(r *http.Request) (*http.Response, error) { + r.Header.Add("x-retry-test-id", wt.testID) + resp, err := wt.rt.RoundTrip(r) //if err != nil{ // log.Printf("Error: %+v", err) //} @@ -245,7 +282,7 @@ func (wi *withInstruction) RoundTrip(r *http.Request) (*http.Response, error) { } // Create custom client that sends instruction -func wrappedClient(instructions []string) (*Client, error) { +func wrappedClient(testID string) (*Client, error) { ctx := context.Background() base := http.DefaultTransport trans, err := htransport.NewTransport(ctx, base, option.WithScopes(raw.DevstorageFullControlScope), @@ -256,7 +293,7 @@ func wrappedClient(instructions []string) (*Client, error) { c := http.Client{Transport: trans} // Add RoundTripper to the created HTTP client. - wrappedTrans := &withInstruction{rt: c.Transport, instructions: instructions} + wrappedTrans := &withTestID{rt: c.Transport, testID: testID} c.Transport = wrappedTrans // Supply this client to storage.NewClient From 36ae41cce258a93031298aae066a18c17ffa3baa Mon Sep 17 00:00:00 2001 From: Chris Cotter Date: Mon, 3 May 2021 14:49:39 -0400 Subject: [PATCH 13/25] gofmt --- storage/conformance_test.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/storage/conformance_test.go b/storage/conformance_test.go index 57ccabd99b2..95b46be5959 100644 --- a/storage/conformance_test.go +++ b/storage/conformance_test.go @@ -149,7 +149,6 @@ var methods = map[string][]retryFunc{ }}, } - func TestRetryConformance(t *testing.T) { host := os.Getenv("STORAGE_EMULATOR_HOST") if host == "" { @@ -212,7 +211,6 @@ func TestRetryConformance(t *testing.T) { t.Errorf("want failure, got success") } - }) } @@ -226,7 +224,7 @@ func TestRetryConformance(t *testing.T) { func createRetryTest(host string, instructions map[string][]string) (string, error) { endpoint := "http://" + host + "/retry_test" c := http.DefaultClient - data := struct{ + data := struct { Instructions map[string][]string `json:"test_instructions"` }{ Instructions: instructions, @@ -241,7 +239,7 @@ func createRetryTest(host string, instructions map[string][]string) (string, err return "", fmt.Errorf("creating retry test: %v", err) } defer res.Body.Close() - testRes := struct{ + testRes := struct { TestID string `json:"id"` }{} if err := json.NewDecoder(res.Body).Decode(&testRes); err != nil { @@ -268,7 +266,7 @@ func deleteRetryTest(host, testID string) error { } type withTestID struct { - rt http.RoundTripper + rt http.RoundTripper testID string } From d8fbc756d0c1022f17349a50236b6a09d7d69d8b Mon Sep 17 00:00:00 2001 From: Chris Cotter Date: Mon, 3 May 2021 20:36:05 -0400 Subject: [PATCH 14/25] add test check and fix endpoints --- storage/conformance_test.go | 74 +++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 24 deletions(-) diff --git a/storage/conformance_test.go b/storage/conformance_test.go index 95b46be5959..d509548ec8d 100644 --- a/storage/conformance_test.go +++ b/storage/conformance_test.go @@ -154,11 +154,12 @@ func TestRetryConformance(t *testing.T) { if host == "" { t.Skip("This test must use the testbench emulator; set STORAGE_EMULATOR_HOST to run.") } + host = "http://" + host ctx := context.Background() // Create non-wrapped client to use for setup steps. - client, err := NewClient(ctx, option.WithEndpoint("http://localhost:9000/storage/v1/")) + client, err := NewClient(ctx, option.WithEndpoint(host + "/storage/v1/")) if err != nil { t.Fatalf("storage.NewClient: %v", err) } @@ -183,14 +184,6 @@ func TestRetryConformance(t *testing.T) { t.Fatalf("setting up retry test: %v", err) } - defer func() { - // Close out test in emulator and verify that all instructions - // were used. - if err := deleteRetryTest(host, testID); err != nil { - t.Errorf("deleting retry test: %v", err) - } - }() - fs := &fixtures{} for _, f := range m.Fixtures { if err := fs.populate(ctx, client, f); err != nil { @@ -199,7 +192,7 @@ func TestRetryConformance(t *testing.T) { } // Create wrapped client which will send emulator instructions. - wrapped, err := wrappedClient(testID) + wrapped, err := wrappedClient(host, testID) if err != nil { t.Errorf("error creating wrapped client: %v", err) } @@ -211,6 +204,17 @@ func TestRetryConformance(t *testing.T) { t.Errorf("want failure, got success") } + // Verify that all instructions were used up during the test + // (indicates that the client sent the correct requests). + if err := checkRetryTest(host, testID); err != nil { + t.Errorf("checking instructions: %v", err) + } + + // Close out test in emulator. + if err := deleteRetryTest(host, testID); err != nil { + t.Errorf("deleting retry test: %v", err) + } + }) } @@ -221,8 +225,10 @@ func TestRetryConformance(t *testing.T) { } +// Create a retry test resource in the emulator. Returns the ID to pass as +// a header in the test execution. func createRetryTest(host string, instructions map[string][]string) (string, error) { - endpoint := "http://" + host + "/retry_test" + endpoint := host + "/retry_test" c := http.DefaultClient data := struct { Instructions map[string][]string `json:"test_instructions"` @@ -234,33 +240,53 @@ func createRetryTest(host string, instructions map[string][]string) (string, err if err := json.NewEncoder(buf).Encode(data); err != nil { return "", fmt.Errorf("encoding request: %v", err) } - res, err := c.Post(endpoint, "application/json", buf) - if err != nil { - return "", fmt.Errorf("creating retry test: %v", err) + resp, err := c.Post(endpoint, "application/json", buf) + if err != nil || resp.StatusCode != 200 { + return "", fmt.Errorf("creating retry test: err: %v, resp: %+v", err, resp) } - defer res.Body.Close() + defer resp.Body.Close() testRes := struct { TestID string `json:"id"` }{} - if err := json.NewDecoder(res.Body).Decode(&testRes); err != nil { + if err := json.NewDecoder(resp.Body).Decode(&testRes); err != nil { return "", fmt.Errorf("decoding test ID: %v", err) } return testRes.TestID, nil } +// Verify that all instructions for a given retry testID have been used up. +func checkRetryTest(host, testID string) error { + endpoint := strings.Join([]string{host, "retry_test", testID}, "/") + c := http.DefaultClient + resp, err := c.Get(endpoint) + if err != nil || resp.StatusCode != 200 { + return fmt.Errorf("getting retry test: err: %v, resp: %+v", err, resp) + } + defer resp.Body.Close() + testRes := struct { + Instructions map[string][]string + Completed bool + }{} + if err := json.NewDecoder(resp.Body).Decode(&testRes); err != nil { + return fmt.Errorf("decoding response: %v", err) + } + if !testRes.Completed { + return fmt.Errorf("test not completed; unused instructions: %+v", testRes.Instructions) + } + return nil +} + +// Delete a retry test resource. func deleteRetryTest(host, testID string) error { - endpoint := "http://" + strings.Join([]string{host, "retry_test", testID}, "/") + endpoint := strings.Join([]string{host, "retry_test", testID}, "/") c := http.DefaultClient req, err := http.NewRequest("DELETE", endpoint, nil) if err != nil { return fmt.Errorf("creating request: %v", err) } resp, err := c.Do(req) - if err != nil { - return fmt.Errorf("deleting test: %v", err) - } - if resp.StatusCode != 200 { - return fmt.Errorf("delete test failed, response: %+v", resp) + if err != nil || resp.StatusCode != 200 { + return fmt.Errorf("deleting test: err: %v, resp: %+v", err, resp) } return nil } @@ -280,7 +306,7 @@ func (wt *withTestID) RoundTrip(r *http.Request) (*http.Response, error) { } // Create custom client that sends instruction -func wrappedClient(testID string) (*Client, error) { +func wrappedClient(host, testID string) (*Client, error) { ctx := context.Background() base := http.DefaultTransport trans, err := htransport.NewTransport(ctx, base, option.WithScopes(raw.DevstorageFullControlScope), @@ -295,7 +321,7 @@ func wrappedClient(testID string) (*Client, error) { c.Transport = wrappedTrans // Supply this client to storage.NewClient - client, err := NewClient(ctx, option.WithHTTPClient(&c), option.WithEndpoint("http://localhost:9000/storage/v1/")) + client, err := NewClient(ctx, option.WithHTTPClient(&c), option.WithEndpoint(host + "/storage/v1/")) return client, err } From ec4ea2055b3913baac26b8bbe6fedad1eb18c92c Mon Sep 17 00:00:00 2001 From: Chris Cotter Date: Mon, 3 May 2021 20:43:40 -0400 Subject: [PATCH 15/25] change fixture to resource --- storage/conformance_test.go | 32 +-- .../test/conformance/retry_tests.json | 32 +-- storage/internal/test/conformance/test.pb.go | 211 ++++++++++-------- storage/internal/test/conformance/test.proto | 8 +- 4 files changed, 149 insertions(+), 134 deletions(-) diff --git a/storage/conformance_test.go b/storage/conformance_test.go index d509548ec8d..ba1b1b89f58 100644 --- a/storage/conformance_test.go +++ b/storage/conformance_test.go @@ -47,18 +47,18 @@ var ( serviceAccountEmail = "my-sevice-account@my-project-id.iam.gserviceaccount.com" ) -// Holds the fixtures for a particular test case. Only the necessary fields will +// Holds the resources for a particular test case. Only the necessary fields will // be populated; others will be nil. -type fixtures struct { +type resources struct { bucket *BucketAttrs object *ObjectAttrs notification *Notification hmacKey *HMACKey } -func (fs *fixtures) populate(ctx context.Context, c *Client, fixture storage_v1_tests.Fixture) error { - switch fixture { - case storage_v1_tests.Fixture_BUCKET: +func (fs *resources) populate(ctx context.Context, c *Client, resource storage_v1_tests.Resource) error { + switch resource { + case storage_v1_tests.Resource_BUCKET: bkt := c.Bucket(bucketIDs.New()) if err := bkt.Create(ctx, projectID, &BucketAttrs{}); err != nil { return fmt.Errorf("creating bucket: %v", err) @@ -68,7 +68,7 @@ func (fs *fixtures) populate(ctx context.Context, c *Client, fixture storage_v1_ return fmt.Errorf("getting bucket attrs: %v", err) } fs.bucket = attrs - case storage_v1_tests.Fixture_OBJECT: + case storage_v1_tests.Resource_OBJECT: // Assumes bucket has been populated first. obj := c.Bucket(fs.bucket.Name).Object(objectIDs.New()) w := obj.NewWriter(ctx) @@ -83,7 +83,7 @@ func (fs *fixtures) populate(ctx context.Context, c *Client, fixture storage_v1_ return fmt.Errorf("getting object attrs: %v", err) } fs.object = attrs - case storage_v1_tests.Fixture_NOTIFICATION: + case storage_v1_tests.Resource_NOTIFICATION: // Assumes bucket has been populated first. n, err := c.Bucket(fs.bucket.Name).AddNotification(ctx, &Notification{ TopicProjectID: projectID, @@ -94,7 +94,7 @@ func (fs *fixtures) populate(ctx context.Context, c *Client, fixture storage_v1_ return fmt.Errorf("adding notification: %v", err) } fs.notification = n - case storage_v1_tests.Fixture_HMAC_KEY: + case storage_v1_tests.Resource_HMAC_KEY: key, err := c.CreateHMACKey(ctx, projectID, serviceAccountEmail) if err != nil { return fmt.Errorf("creating HMAC key: %v", err) @@ -104,7 +104,7 @@ func (fs *fixtures) populate(ctx context.Context, c *Client, fixture storage_v1_ return nil } -type retryFunc func(ctx context.Context, c *Client, fs *fixtures, preconditions bool) error +type retryFunc func(ctx context.Context, c *Client, fs *resources, preconditions bool) error // Methods to retry. This is a map whose keys are a string describing a standard // API call (e.g. storage.objects.get) and values are a list of functions which @@ -113,11 +113,11 @@ type retryFunc func(ctx context.Context, c *Client, fs *fixtures, preconditions // read or just a metadata get). var methods = map[string][]retryFunc{ "storage.objects.get": { - func(ctx context.Context, c *Client, fs *fixtures, _ bool) error { + func(ctx context.Context, c *Client, fs *resources, _ bool) error { _, err := c.Bucket(fs.bucket.Name).Object(fs.object.Name).Attrs(ctx) return err }, - func(ctx context.Context, c *Client, fs *fixtures, _ bool) error { + func(ctx context.Context, c *Client, fs *resources, _ bool) error { r, err := c.Bucket(fs.bucket.Name).Object(fs.object.Name).NewReader(ctx) if err != nil { return err @@ -127,7 +127,7 @@ var methods = map[string][]retryFunc{ }, }, "storage.objects.update": { - func(ctx context.Context, c *Client, fs *fixtures, preconditions bool) error { + func(ctx context.Context, c *Client, fs *resources, preconditions bool) error { uattrs := ObjectAttrsToUpdate{Metadata: map[string]string{"foo": "bar"}} obj := c.Bucket(fs.bucket.Name).Object(fs.object.Name) if preconditions { @@ -138,7 +138,7 @@ var methods = map[string][]retryFunc{ }, }, "storage.buckets.update": { - func(ctx context.Context, c *Client, fs *fixtures, preconditions bool) error { + func(ctx context.Context, c *Client, fs *resources, preconditions bool) error { uattrs := BucketAttrsToUpdate{StorageClass: "ARCHIVE"} bkt := c.Bucket(fs.bucket.Name) if preconditions { @@ -184,10 +184,10 @@ func TestRetryConformance(t *testing.T) { t.Fatalf("setting up retry test: %v", err) } - fs := &fixtures{} - for _, f := range m.Fixtures { + fs := &resources{} + for _, f := range m.Resources { if err := fs.populate(ctx, client, f); err != nil { - t.Fatalf("creating test fixtures: %v", err) + t.Fatalf("creating test resources: %v", err) } } diff --git a/storage/internal/test/conformance/retry_tests.json b/storage/internal/test/conformance/retry_tests.json index d635e9edfce..ee800d9f0d4 100644 --- a/storage/internal/test/conformance/retry_tests.json +++ b/storage/internal/test/conformance/retry_tests.json @@ -15,8 +15,8 @@ } ], "methods": [ - {"name": "storage.buckets.get", "fixtures": ["BUCKET"]}, - {"name": "storage.objects.get", "fixtures": ["BUCKET", "OBJECT"]} + {"name": "storage.buckets.get", "resources": ["BUCKET"]}, + {"name": "storage.objects.get", "resources": ["BUCKET", "OBJECT"]} ], "preconditionProvided": false, "expectSuccess": true @@ -36,10 +36,10 @@ } ], "methods": [ - {"name": "storage.buckets.insert", "fixtures": []}, - {"name": "storage.buckets.update", "fixtures": ["BUCKET"]}, - {"name": "storage.objects.insert", "fixtures": ["BUCKET"]}, - {"name": "storage.objects.update", "fixtures": ["BUCKET", "OBJECT"]} + {"name": "storage.buckets.insert", "resources": []}, + {"name": "storage.buckets.update", "resources": ["BUCKET"]}, + {"name": "storage.objects.insert", "resources": ["BUCKET"]}, + {"name": "storage.objects.update", "resources": ["BUCKET", "OBJECT"]} ], "preconditionProvided": true, "expectSuccess": true @@ -59,10 +59,10 @@ } ], "methods": [ - {"name": "storage.buckets.insert", "fixtures": []}, - {"name": "storage.buckets.update", "fixtures": ["BUCKET"]}, - {"name": "storage.objects.insert", "fixtures": ["BUCKET"]}, - {"name": "storage.objects.update", "fixtures": ["BUCKET", "OBJECT"]} + {"name": "storage.buckets.insert", "resources": []}, + {"name": "storage.buckets.update", "resources": ["BUCKET"]}, + {"name": "storage.objects.insert", "resources": ["BUCKET"]}, + {"name": "storage.objects.update", "resources": ["BUCKET", "OBJECT"]} ], "preconditionProvided": false, "expectSuccess": false @@ -79,12 +79,12 @@ } ], "methods": [ - {"name": "storage.objects.get", "fixtures": ["BUCKET", "OBJECT"]}, - {"name": "storage.buckets.get", "fixtures": ["BUCKET"]}, - {"name": "storage.buckets.insert", "fixtures": []}, - {"name": "storage.buckets.update", "fixtures": ["BUCKET"]}, - {"name": "storage.objects.insert", "fixtures": ["BUCKET"]}, - {"name": "storage.objects.update", "fixtures": ["BUCKET", "OBJECT"]} + {"name": "storage.objects.get", "resources": ["BUCKET", "OBJECT"]}, + {"name": "storage.buckets.get", "resources": ["BUCKET"]}, + {"name": "storage.buckets.insert", "resources": []}, + {"name": "storage.buckets.update", "resources": ["BUCKET"]}, + {"name": "storage.objects.insert", "resources": ["BUCKET"]}, + {"name": "storage.objects.update", "resources": ["BUCKET", "OBJECT"]} ], "preconditionProvided": false, "expectSuccess": false diff --git a/storage/internal/test/conformance/test.pb.go b/storage/internal/test/conformance/test.pb.go index 6513ae221e1..ffc3e59746a 100644 --- a/storage/internal/test/conformance/test.pb.go +++ b/storage/internal/test/conformance/test.pb.go @@ -49,34 +49,36 @@ func (UrlStyle) EnumDescriptor() ([]byte, []int) { return fileDescriptor_c161fcfdc0c3ff1e, []int{0} } -type Fixture int32 +// Test resources that are necessary for a method call. For example, +// storage.objects.get would require BUCKET and OBJECT. +type Resource int32 const ( - Fixture_BUCKET Fixture = 0 - Fixture_OBJECT Fixture = 1 - Fixture_NOTIFICATION Fixture = 2 - Fixture_HMAC_KEY Fixture = 3 + Resource_BUCKET Resource = 0 + Resource_OBJECT Resource = 1 + Resource_NOTIFICATION Resource = 2 + Resource_HMAC_KEY Resource = 3 ) -var Fixture_name = map[int32]string{ +var Resource_name = map[int32]string{ 0: "BUCKET", 1: "OBJECT", 2: "NOTIFICATION", 3: "HMAC_KEY", } -var Fixture_value = map[string]int32{ +var Resource_value = map[string]int32{ "BUCKET": 0, "OBJECT": 1, "NOTIFICATION": 2, "HMAC_KEY": 3, } -func (x Fixture) String() string { - return proto.EnumName(Fixture_name, int32(x)) +func (x Resource) String() string { + return proto.EnumName(Resource_name, int32(x)) } -func (Fixture) EnumDescriptor() ([]byte, []int) { +func (Resource) EnumDescriptor() ([]byte, []int) { return fileDescriptor_c161fcfdc0c3ff1e, []int{1} } @@ -585,6 +587,8 @@ func (m *PostPolicyV4Test) GetPolicyOutput() *PolicyOutput { return nil } +// A list of instructions to send as headers to the GCS emulator. Each +// instruction will force a specified failure for that request. type InstructionList struct { Instructions []string `protobuf:"bytes,1,rep,name=instructions,proto3" json:"instructions,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` @@ -624,12 +628,14 @@ func (m *InstructionList) GetInstructions() []string { return nil } +// A particular storage API method and required resources in order to test it. +// Methods must be implemented in tests for each language. type Method struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Fixtures []Fixture `protobuf:"varint,2,rep,packed,name=fixtures,proto3,enum=google.cloud.conformance.storage.v1.Fixture" json:"fixtures,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Resources []Resource `protobuf:"varint,2,rep,packed,name=resources,proto3,enum=google.cloud.conformance.storage.v1.Resource" json:"resources,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *Method) Reset() { *m = Method{} } @@ -664,23 +670,32 @@ func (m *Method) GetName() string { return "" } -func (m *Method) GetFixtures() []Fixture { +func (m *Method) GetResources() []Resource { if m != nil { - return m.Fixtures + return m.Resources } return nil } +// Schema for a retry test, corresponding to a single scenario from the design +// doc. type RetryTest struct { - Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` - Cases []*InstructionList `protobuf:"bytes,3,rep,name=cases,proto3" json:"cases,omitempty"` - Methods []*Method `protobuf:"bytes,4,rep,name=methods,proto3" json:"methods,omitempty"` - PreconditionProvided bool `protobuf:"varint,5,opt,name=preconditionProvided,proto3" json:"preconditionProvided,omitempty"` - ExpectSuccess bool `protobuf:"varint,6,opt,name=expectSuccess,proto3" json:"expectSuccess,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + // Human-readable description of the test case. + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + // List of emulator instructions. + Cases []*InstructionList `protobuf:"bytes,3,rep,name=cases,proto3" json:"cases,omitempty"` + // List of API methods to be tested. + Methods []*Method `protobuf:"bytes,4,rep,name=methods,proto3" json:"methods,omitempty"` + // Whether a precondition is provided (for conditionally-idempotent methods + // only). + PreconditionProvided bool `protobuf:"varint,5,opt,name=preconditionProvided,proto3" json:"preconditionProvided,omitempty"` + // Whether we expect the method calls to eventually succeed after the client + // library retries. + ExpectSuccess bool `protobuf:"varint,6,opt,name=expectSuccess,proto3" json:"expectSuccess,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *RetryTest) Reset() { *m = RetryTest{} } @@ -752,7 +767,7 @@ func (m *RetryTest) GetExpectSuccess() bool { func init() { proto.RegisterEnum("google.cloud.conformance.storage.v1.UrlStyle", UrlStyle_name, UrlStyle_value) - proto.RegisterEnum("google.cloud.conformance.storage.v1.Fixture", Fixture_name, Fixture_value) + proto.RegisterEnum("google.cloud.conformance.storage.v1.Resource", Resource_name, Resource_value) proto.RegisterType((*TestFile)(nil), "google.cloud.conformance.storage.v1.TestFile") proto.RegisterType((*SigningV4Test)(nil), "google.cloud.conformance.storage.v1.SigningV4Test") proto.RegisterMapType((map[string]string)(nil), "google.cloud.conformance.storage.v1.SigningV4Test.HeadersEntry") @@ -772,75 +787,75 @@ func init() { func init() { proto.RegisterFile("test.proto", fileDescriptor_c161fcfdc0c3ff1e) } var fileDescriptor_c161fcfdc0c3ff1e = []byte{ - // 1120 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xdf, 0x8e, 0xda, 0xc6, - 0x17, 0x8e, 0x61, 0x61, 0xe1, 0x40, 0x88, 0x7f, 0xf3, 0xdb, 0x54, 0x2e, 0x17, 0x2d, 0xa2, 0x95, - 0xba, 0x4d, 0x5b, 0x27, 0xa1, 0x1b, 0x29, 0x8d, 0x5a, 0x55, 0x40, 0xd8, 0x40, 0xb2, 0xbb, 0x50, - 0x63, 0x36, 0x5a, 0xa9, 0x12, 0xf2, 0xda, 0x03, 0xb8, 0x31, 0x1e, 0xef, 0xcc, 0x78, 0xb5, 0xbc, - 0x47, 0x5f, 0xa0, 0xb7, 0x79, 0xa9, 0x5e, 0x55, 0xea, 0x63, 0x54, 0x9e, 0xb1, 0xc1, 0x6c, 0x58, - 0x09, 0xfa, 0xe7, 0x6e, 0xe6, 0x9c, 0xf9, 0xbe, 0x33, 0x73, 0xe6, 0x9b, 0x33, 0x07, 0x80, 0x63, - 0xc6, 0xf5, 0x80, 0x12, 0x4e, 0xd0, 0x67, 0x53, 0x42, 0xa6, 0x1e, 0xd6, 0x6d, 0x8f, 0x84, 0x8e, - 0x6e, 0x13, 0x7f, 0x42, 0xe8, 0xdc, 0xf2, 0x6d, 0xac, 0x33, 0x4e, 0xa8, 0x35, 0xc5, 0xfa, 0xf5, - 0xd3, 0xea, 0xa7, 0x72, 0xd1, 0x63, 0x01, 0xb9, 0x0c, 0x27, 0x8f, 0xb9, 0x3b, 0xc7, 0x8c, 0x5b, - 0xf3, 0x40, 0xb2, 0xd4, 0x7f, 0xcb, 0x40, 0xc1, 0xc4, 0x8c, 0x1f, 0xbb, 0x1e, 0x46, 0x3f, 0x83, - 0xca, 0xdc, 0xa9, 0xef, 0xfa, 0xd3, 0xf1, 0xf5, 0xd1, 0x38, 0x8a, 0xc5, 0x34, 0xa5, 0x96, 0x3d, - 0x2c, 0x35, 0x1a, 0xfa, 0x16, 0xd1, 0xf4, 0xa1, 0x04, 0x9f, 0x1f, 0x45, 0x8c, 0x46, 0x85, 0xa5, - 0xa7, 0x0c, 0x4d, 0xe0, 0x20, 0x20, 0x8c, 0x8f, 0x03, 0xe2, 0xb9, 0xf6, 0x62, 0x15, 0x21, 0x23, - 0x22, 0x3c, 0xdb, 0x2a, 0xc2, 0x80, 0x30, 0x3e, 0x10, 0xf8, 0x38, 0xc8, 0xff, 0x82, 0x5b, 0x16, - 0x86, 0xfa, 0x50, 0xa2, 0x98, 0xd3, 0x45, 0x4c, 0x9f, 0x15, 0xf4, 0xfa, 0x56, 0xf4, 0x46, 0x84, - 0x13, 0xbc, 0x40, 0x93, 0x21, 0xab, 0xff, 0x91, 0x87, 0xfb, 0x6b, 0x47, 0x43, 0x55, 0x28, 0x4c, - 0x5c, 0x0f, 0x9f, 0x59, 0x73, 0xac, 0x29, 0x35, 0xe5, 0xb0, 0x68, 0x2c, 0xe7, 0xa8, 0x06, 0x25, - 0x07, 0x33, 0x9b, 0xba, 0x01, 0x77, 0x89, 0xaf, 0x65, 0x84, 0x3b, 0x6d, 0x42, 0x1f, 0x41, 0xfe, - 0x32, 0xb4, 0xdf, 0x61, 0xae, 0x65, 0x85, 0x33, 0x9e, 0x45, 0x76, 0x72, 0xf9, 0x0b, 0xb6, 0xb9, - 0xb6, 0x27, 0xed, 0x72, 0x16, 0xd9, 0xe7, 0x98, 0xcf, 0x88, 0xa3, 0xe5, 0xa4, 0x5d, 0xce, 0xd0, - 0x27, 0x00, 0xf8, 0x26, 0x70, 0xa9, 0x25, 0x02, 0xe5, 0x6b, 0xca, 0x61, 0xd6, 0x48, 0x59, 0xd0, - 0x73, 0x28, 0x2e, 0xaf, 0x5b, 0xdb, 0xaf, 0x29, 0x87, 0xa5, 0x46, 0x35, 0x49, 0x43, 0x22, 0x08, - 0xdd, 0x4c, 0x56, 0x18, 0xab, 0xc5, 0xd1, 0x19, 0xf0, 0x4d, 0x80, 0x6d, 0x8e, 0x9d, 0x11, 0xf5, - 0xb4, 0x82, 0x3c, 0x43, 0xca, 0x84, 0x2e, 0x60, 0x7f, 0x86, 0x2d, 0x07, 0x53, 0xa6, 0x15, 0x45, - 0x82, 0x7f, 0xdc, 0x5d, 0x21, 0x7a, 0x57, 0x32, 0x74, 0x7c, 0x4e, 0x17, 0x46, 0xc2, 0x87, 0x28, - 0xa8, 0x57, 0x21, 0xa6, 0x8b, 0x71, 0x60, 0x51, 0x6b, 0x8e, 0x79, 0x14, 0x03, 0x44, 0x8c, 0x57, - 0x7f, 0x23, 0xc6, 0x4f, 0x11, 0xd5, 0x60, 0xc9, 0x24, 0x63, 0x3d, 0xb8, 0x5a, 0xb7, 0x46, 0x29, - 0x66, 0xf6, 0x0c, 0xcf, 0xb1, 0x56, 0x92, 0x29, 0x96, 0x33, 0xd4, 0x83, 0x42, 0x48, 0xbd, 0x21, - 0x5f, 0x78, 0x58, 0x2b, 0xd7, 0x94, 0xc3, 0x4a, 0xe3, 0x9b, 0xad, 0xf6, 0x30, 0x8a, 0x41, 0xc6, - 0x12, 0x8e, 0x9e, 0xc0, 0xff, 0xe5, 0x3d, 0xb7, 0x48, 0xe8, 0x3b, 0x5d, 0xc2, 0xb8, 0x1f, 0xc9, - 0xe7, 0xbe, 0x88, 0xb7, 0xc9, 0x85, 0x5e, 0x80, 0x96, 0xa4, 0xbc, 0x6d, 0xf9, 0xc4, 0x77, 0x6d, - 0xcb, 0x33, 0xf0, 0x55, 0x88, 0x19, 0xd7, 0x2a, 0x02, 0x76, 0xa7, 0x1f, 0x35, 0xe0, 0x20, 0xf1, - 0x0d, 0x39, 0x75, 0xfd, 0xa9, 0x49, 0xa2, 0xbc, 0x68, 0x0f, 0x04, 0x6e, 0xa3, 0xaf, 0xfa, 0x02, - 0xca, 0xe9, 0x1b, 0x41, 0x2a, 0x64, 0xdf, 0xe1, 0x45, 0x2c, 0xf0, 0x68, 0x88, 0x0e, 0x20, 0x77, - 0x6d, 0x79, 0x21, 0x8e, 0x55, 0x2d, 0x27, 0x2f, 0x32, 0xcf, 0x95, 0x6a, 0x0b, 0x0e, 0x36, 0x65, - 0x7a, 0x17, 0x8e, 0xfa, 0x11, 0xa0, 0x36, 0xf1, 0x1d, 0x37, 0x12, 0xaf, 0xe5, 0x9d, 0x5a, 0xdc, - 0x9e, 0x61, 0x16, 0xab, 0x9c, 0x62, 0xc6, 0x22, 0x95, 0x47, 0xe5, 0xa8, 0x68, 0xa4, 0x2c, 0xf5, - 0x4b, 0x50, 0xe5, 0xfb, 0x5f, 0x62, 0x19, 0xd2, 0x01, 0xd9, 0xc4, 0xe7, 0xd8, 0xe7, 0x27, 0xd8, - 0x9f, 0xf2, 0x99, 0x61, 0xf9, 0x53, 0x2c, 0xb0, 0x39, 0x63, 0x83, 0x27, 0x8a, 0xc1, 0xb8, 0x45, - 0x39, 0x7b, 0xeb, 0xf2, 0x99, 0x28, 0x48, 0x45, 0x23, 0x65, 0xa9, 0xff, 0xba, 0x07, 0x25, 0x19, - 0xa4, 0xe7, 0x07, 0x21, 0x4f, 0xc9, 0x45, 0xb9, 0x53, 0x2e, 0x99, 0xff, 0x44, 0x2e, 0xd9, 0xbb, - 0xe5, 0xb2, 0x2a, 0x2b, 0x7b, 0x77, 0x94, 0x95, 0xdc, 0x5a, 0x59, 0xf9, 0xb0, 0x7c, 0xe4, 0xfe, - 0xa5, 0xf2, 0x61, 0x42, 0x7e, 0xe2, 0x62, 0xcf, 0x61, 0x5a, 0x41, 0xbc, 0xdb, 0xef, 0xb7, 0xac, - 0xed, 0xcb, 0x04, 0xeb, 0xc7, 0x02, 0x2e, 0x1f, 0x6b, 0xcc, 0x85, 0x46, 0x00, 0xf6, 0xf2, 0x8a, - 0xb5, 0xa2, 0xd8, 0xd0, 0xb3, 0x1d, 0x98, 0x57, 0xfa, 0x30, 0x52, 0x44, 0xd5, 0xef, 0xa0, 0x94, - 0x8a, 0xb6, 0x93, 0x60, 0xff, 0x54, 0xa0, 0x2c, 0xb9, 0xfb, 0x21, 0x8f, 0x74, 0xa1, 0x42, 0x36, - 0xa4, 0x5e, 0x02, 0x0e, 0xa9, 0x87, 0x46, 0xcb, 0x54, 0xc8, 0x6f, 0xee, 0x87, 0x1d, 0x36, 0x2c, - 0x49, 0x37, 0xe6, 0xe2, 0x08, 0x1e, 0x26, 0x4f, 0xf8, 0x25, 0xb6, 0x89, 0x83, 0x1d, 0x09, 0x89, - 0xf5, 0xb1, 0xd9, 0xf9, 0x4f, 0x8e, 0xfa, 0xbb, 0x12, 0x3d, 0xb3, 0xf5, 0xaf, 0xf6, 0xf6, 0x57, - 0xa7, 0x7c, 0xf8, 0xd5, 0x19, 0x50, 0x0a, 0x56, 0xd7, 0x2a, 0x68, 0x4b, 0x8d, 0x27, 0xbb, 0xca, - 0xc1, 0x48, 0x93, 0xa0, 0x11, 0x94, 0x83, 0x54, 0x7e, 0xc4, 0x91, 0x4b, 0x8d, 0xa7, 0x3b, 0x27, - 0xd6, 0x58, 0xa3, 0xa9, 0x3f, 0x83, 0x07, 0x3d, 0x9f, 0x71, 0x1a, 0xda, 0xd1, 0xce, 0x4f, 0x5c, - 0xc6, 0x51, 0x1d, 0xca, 0xee, 0xca, 0xc4, 0xe2, 0xe2, 0xb3, 0x66, 0xab, 0x4f, 0x20, 0x7f, 0x2a, - 0xbf, 0x63, 0x04, 0x7b, 0xfe, 0xaa, 0x21, 0x10, 0x63, 0xd4, 0x8d, 0x1a, 0x85, 0x1b, 0x1e, 0x52, - 0x2c, 0x05, 0x50, 0x69, 0x7c, 0xbd, 0xd5, 0x3e, 0x8f, 0x25, 0xc8, 0x58, 0xa2, 0xeb, 0xef, 0x33, - 0x50, 0x5c, 0xb6, 0x27, 0xa8, 0x02, 0x19, 0xd7, 0x11, 0x91, 0x72, 0x46, 0xc6, 0x75, 0xb6, 0x68, - 0x3a, 0x5e, 0x43, 0xce, 0xb6, 0x18, 0x4e, 0xfa, 0xa1, 0xa3, 0xad, 0xb6, 0x71, 0x2b, 0x21, 0x86, - 0xa4, 0x40, 0x1d, 0xd8, 0x97, 0x2d, 0x08, 0xd3, 0xf6, 0x04, 0xdb, 0x57, 0x5b, 0xb1, 0xc9, 0x3c, - 0x19, 0x09, 0x36, 0xfa, 0xa3, 0x02, 0x8a, 0x97, 0x4f, 0x71, 0x40, 0xc9, 0xb5, 0xeb, 0x60, 0xd9, - 0xe5, 0x14, 0x8c, 0x8d, 0x3e, 0xf4, 0x39, 0xdc, 0x97, 0xda, 0x1e, 0x86, 0xb6, 0x8d, 0x19, 0x13, - 0x75, 0xab, 0x60, 0xac, 0x1b, 0x1f, 0xf5, 0xa1, 0x90, 0x94, 0x54, 0x54, 0x01, 0x18, 0x34, 0xcd, - 0xee, 0x78, 0x68, 0x5e, 0x9c, 0x74, 0xd4, 0x7b, 0x48, 0x83, 0x83, 0xf3, 0x9e, 0x61, 0x8e, 0x9a, - 0x27, 0xe3, 0x6e, 0x7f, 0x68, 0x76, 0x5e, 0xc6, 0x1e, 0x05, 0x7d, 0x0c, 0x0f, 0x5b, 0xa3, 0xf6, - 0x9b, 0x8e, 0x39, 0x6e, 0xf5, 0x47, 0x67, 0x2f, 0x85, 0xfb, 0xac, 0x79, 0xda, 0x51, 0x33, 0x8f, - 0x9a, 0xb0, 0x1f, 0x5f, 0x09, 0x02, 0xc8, 0xcb, 0x55, 0xea, 0xbd, 0x68, 0xdc, 0x6f, 0xbd, 0xee, - 0xb4, 0x4d, 0x55, 0x41, 0x2a, 0x94, 0xcf, 0xfa, 0x66, 0xef, 0xb8, 0xd7, 0x6e, 0x9a, 0xbd, 0xfe, - 0x99, 0x9a, 0x41, 0x65, 0x28, 0x74, 0x4f, 0x9b, 0xed, 0xf1, 0x9b, 0xce, 0x85, 0x9a, 0x6d, 0xbd, - 0x85, 0x2f, 0x6c, 0x32, 0xdf, 0x26, 0x51, 0x03, 0xe5, 0x7d, 0xe6, 0xcb, 0x57, 0x72, 0x5d, 0x5b, - 0xac, 0x1b, 0xc6, 0xbe, 0xf3, 0xa7, 0xba, 0x68, 0x49, 0xf5, 0xf6, 0x0a, 0x78, 0x99, 0x17, 0xc5, - 0xf8, 0xdb, 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0x13, 0x63, 0x45, 0x57, 0x1d, 0x0c, 0x00, 0x00, + // 1116 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xdd, 0x6e, 0xdb, 0x36, + 0x14, 0xae, 0xec, 0xd8, 0xb5, 0x8f, 0xdd, 0x54, 0xe3, 0xd2, 0x41, 0xf3, 0xc5, 0x66, 0x78, 0x03, + 0x96, 0x75, 0x98, 0xda, 0x7a, 0x29, 0xd0, 0x15, 0x1b, 0x86, 0xd8, 0x71, 0x1a, 0x37, 0x3f, 0xf6, + 0x68, 0x39, 0x45, 0x80, 0x01, 0x86, 0x22, 0x31, 0xb6, 0x56, 0x59, 0x54, 0x48, 0x2a, 0xa8, 0xdf, + 0x63, 0x2f, 0xb0, 0xdb, 0xbe, 0xd4, 0xae, 0x06, 0xec, 0x31, 0x06, 0x91, 0x92, 0x2d, 0xa7, 0x0e, + 0x60, 0xef, 0xe7, 0x4e, 0x3c, 0x87, 0xdf, 0xf7, 0x89, 0x87, 0x1f, 0x0f, 0x09, 0x20, 0x08, 0x17, + 0x66, 0xc8, 0xa8, 0xa0, 0xe8, 0x8b, 0x31, 0xa5, 0x63, 0x9f, 0x98, 0x8e, 0x4f, 0x23, 0xd7, 0x74, + 0x68, 0x70, 0x45, 0xd9, 0xd4, 0x0e, 0x1c, 0x62, 0x72, 0x41, 0x99, 0x3d, 0x26, 0xe6, 0xcd, 0xb3, + 0xda, 0xe7, 0x6a, 0xd2, 0x13, 0x09, 0xb9, 0x8c, 0xae, 0x9e, 0x08, 0x6f, 0x4a, 0xb8, 0xb0, 0xa7, + 0xa1, 0x62, 0x69, 0xfc, 0x9e, 0x83, 0x92, 0x45, 0xb8, 0x38, 0xf4, 0x7c, 0x82, 0x7e, 0x01, 0x9d, + 0x7b, 0xe3, 0xc0, 0x0b, 0xc6, 0xa3, 0x9b, 0xbd, 0x51, 0xac, 0xc5, 0x0d, 0xad, 0x9e, 0xdf, 0xad, + 0x34, 0x9b, 0xe6, 0x1a, 0x6a, 0xe6, 0x40, 0x81, 0xcf, 0xf7, 0x62, 0x46, 0xbc, 0xcd, 0xb3, 0x43, + 0x8e, 0xae, 0x60, 0x27, 0xa4, 0x5c, 0x8c, 0x42, 0xea, 0x7b, 0xce, 0x6c, 0xa1, 0x90, 0x93, 0x0a, + 0xcf, 0xd7, 0x52, 0xe8, 0x53, 0x2e, 0xfa, 0x12, 0x9f, 0x88, 0x7c, 0x14, 0xde, 0x8a, 0x70, 0xd4, + 0x83, 0x0a, 0x23, 0x82, 0xcd, 0x12, 0xfa, 0xbc, 0xa4, 0x37, 0xd7, 0xa2, 0xc7, 0x31, 0x4e, 0xf2, + 0x02, 0x4b, 0x3f, 0x79, 0xe3, 0xcf, 0x22, 0x3c, 0x58, 0x5a, 0x1a, 0xaa, 0x41, 0xe9, 0xca, 0xf3, + 0xc9, 0x99, 0x3d, 0x25, 0x86, 0x56, 0xd7, 0x76, 0xcb, 0x78, 0x3e, 0x46, 0x75, 0xa8, 0xb8, 0x84, + 0x3b, 0xcc, 0x0b, 0x85, 0x47, 0x03, 0x23, 0x27, 0xd3, 0xd9, 0x10, 0xfa, 0x04, 0x8a, 0x97, 0x91, + 0xf3, 0x96, 0x08, 0x23, 0x2f, 0x93, 0xc9, 0x28, 0x8e, 0xd3, 0xcb, 0x5f, 0x89, 0x23, 0x8c, 0x2d, + 0x15, 0x57, 0xa3, 0x38, 0x3e, 0x25, 0x62, 0x42, 0x5d, 0xa3, 0xa0, 0xe2, 0x6a, 0x84, 0x3e, 0x03, + 0x20, 0xef, 0x42, 0x8f, 0xd9, 0x52, 0xa8, 0x58, 0xd7, 0x76, 0xf3, 0x38, 0x13, 0x41, 0x2f, 0xa0, + 0x3c, 0xdf, 0x6e, 0xe3, 0x7e, 0x5d, 0xdb, 0xad, 0x34, 0x6b, 0x69, 0x19, 0x52, 0x43, 0x98, 0x56, + 0x3a, 0x03, 0x2f, 0x26, 0xc7, 0x6b, 0x20, 0xef, 0x42, 0xe2, 0x08, 0xe2, 0x0e, 0x99, 0x6f, 0x94, + 0xd4, 0x1a, 0x32, 0x21, 0x74, 0x01, 0xf7, 0x27, 0xc4, 0x76, 0x09, 0xe3, 0x46, 0x59, 0x16, 0xf8, + 0xa7, 0xcd, 0x1d, 0x62, 0x1e, 0x29, 0x86, 0x4e, 0x20, 0xd8, 0x0c, 0xa7, 0x7c, 0x88, 0x81, 0x7e, + 0x1d, 0x11, 0x36, 0x1b, 0x85, 0x36, 0xb3, 0xa7, 0x44, 0xc4, 0x1a, 0x20, 0x35, 0x5e, 0xfd, 0x03, + 0x8d, 0x9f, 0x63, 0xaa, 0xfe, 0x9c, 0x49, 0x69, 0x3d, 0xbc, 0x5e, 0x8e, 0xc6, 0x25, 0xe6, 0xce, + 0x84, 0x4c, 0x89, 0x51, 0x51, 0x25, 0x56, 0x23, 0xd4, 0x85, 0x52, 0xc4, 0xfc, 0x81, 0x98, 0xf9, + 0xc4, 0xa8, 0xd6, 0xb5, 0xdd, 0xed, 0xe6, 0xb7, 0x6b, 0xfd, 0xc3, 0x30, 0x01, 0xe1, 0x39, 0x1c, + 0x3d, 0x85, 0x8f, 0xd5, 0x3e, 0xb7, 0x68, 0x14, 0xb8, 0x47, 0x94, 0x8b, 0x20, 0xb6, 0xcf, 0x03, + 0xa9, 0xb7, 0x2a, 0x85, 0x5e, 0x82, 0x91, 0x96, 0xbc, 0x6d, 0x07, 0x34, 0xf0, 0x1c, 0xdb, 0xc7, + 0xe4, 0x3a, 0x22, 0x5c, 0x18, 0xdb, 0x12, 0x76, 0x67, 0x1e, 0x35, 0x61, 0x27, 0xcd, 0x0d, 0x04, + 0xf3, 0x82, 0xb1, 0x45, 0xe3, 0xba, 0x18, 0x0f, 0x25, 0x6e, 0x65, 0xae, 0xf6, 0x12, 0xaa, 0xd9, + 0x1d, 0x41, 0x3a, 0xe4, 0xdf, 0x92, 0x59, 0x62, 0xf0, 0xf8, 0x13, 0xed, 0x40, 0xe1, 0xc6, 0xf6, + 0x23, 0x92, 0xb8, 0x5a, 0x0d, 0x5e, 0xe6, 0x5e, 0x68, 0xb5, 0x16, 0xec, 0xac, 0xaa, 0xf4, 0x26, + 0x1c, 0x8d, 0x3d, 0x40, 0x6d, 0x1a, 0xb8, 0x5e, 0x6c, 0x5e, 0xdb, 0x3f, 0xb5, 0x85, 0x33, 0x21, + 0x3c, 0x71, 0x39, 0x23, 0x9c, 0xc7, 0x2e, 0x8f, 0xdb, 0x51, 0x19, 0x67, 0x22, 0x8d, 0x4b, 0xd0, + 0xd5, 0xf9, 0x9f, 0x63, 0x39, 0x32, 0x01, 0x39, 0x34, 0x10, 0x24, 0x10, 0x27, 0x24, 0x18, 0x8b, + 0x09, 0xb6, 0x83, 0x31, 0x91, 0xd8, 0x02, 0x5e, 0x91, 0x89, 0x35, 0xb8, 0xb0, 0x99, 0xe0, 0x6f, + 0x3c, 0x31, 0x91, 0x0d, 0xa9, 0x8c, 0x33, 0x91, 0xc6, 0x6f, 0x5b, 0x50, 0x51, 0x22, 0xdd, 0x20, + 0x8c, 0x44, 0xc6, 0x2e, 0xda, 0x9d, 0x76, 0xc9, 0xfd, 0x2f, 0x76, 0xc9, 0xdf, 0x6d, 0x97, 0x45, + 0x5b, 0xd9, 0xba, 0xa3, 0xad, 0x14, 0x96, 0xda, 0xca, 0x87, 0xed, 0xa3, 0xf0, 0x1f, 0xb5, 0x0f, + 0x0b, 0x8a, 0x57, 0x1e, 0xf1, 0x5d, 0x6e, 0x94, 0xe4, 0xb9, 0xfd, 0x61, 0xcd, 0xde, 0x3e, 0x2f, + 0xb0, 0x79, 0x28, 0xe1, 0xea, 0xb0, 0x26, 0x5c, 0x68, 0x08, 0xe0, 0xcc, 0xb7, 0xd8, 0x28, 0xcb, + 0x1f, 0x7a, 0xbe, 0x01, 0xf3, 0xc2, 0x1f, 0x38, 0x43, 0x54, 0xfb, 0x1e, 0x2a, 0x19, 0xb5, 0x8d, + 0x0c, 0xfb, 0x97, 0x06, 0x55, 0xc5, 0xdd, 0x8b, 0x44, 0xec, 0x0b, 0x1d, 0xf2, 0x11, 0xf3, 0x53, + 0x70, 0xc4, 0x7c, 0x34, 0x9c, 0x97, 0x42, 0x5d, 0x73, 0x3f, 0x6e, 0xf0, 0xc3, 0x8a, 0x74, 0x65, + 0x2d, 0xf6, 0xe0, 0x51, 0x7a, 0x84, 0x0f, 0x88, 0x43, 0x5d, 0xe2, 0x2a, 0x48, 0xe2, 0x8f, 0xd5, + 0xc9, 0x7f, 0xb3, 0xd4, 0x3f, 0xb4, 0xf8, 0x98, 0x2d, 0x5f, 0xb5, 0xb7, 0xaf, 0x3a, 0xed, 0xc3, + 0xab, 0x0e, 0x43, 0x25, 0x5c, 0x6c, 0xab, 0xa4, 0xad, 0x34, 0x9f, 0x6e, 0x6a, 0x07, 0x9c, 0x25, + 0x41, 0x43, 0xa8, 0x86, 0x99, 0xfa, 0xc8, 0x25, 0x57, 0x9a, 0xcf, 0x36, 0x2e, 0x2c, 0x5e, 0xa2, + 0x69, 0x3c, 0x87, 0x87, 0xdd, 0x80, 0x0b, 0x16, 0x39, 0xf1, 0x9f, 0x9f, 0x78, 0x5c, 0xa0, 0x06, + 0x54, 0xbd, 0x45, 0x88, 0x27, 0xcd, 0x67, 0x29, 0xd6, 0xf0, 0xa0, 0x78, 0xaa, 0xae, 0x63, 0x04, + 0x5b, 0xc1, 0xe2, 0x41, 0x20, 0xbf, 0xd1, 0x31, 0x94, 0x19, 0xe1, 0x34, 0x62, 0x0e, 0x51, 0x0e, + 0x58, 0xb7, 0x23, 0xe0, 0x04, 0x85, 0x17, 0xf8, 0xc6, 0xfb, 0x1c, 0x94, 0xe7, 0x2f, 0x14, 0xb4, + 0x0d, 0x39, 0xcf, 0x95, 0x62, 0x05, 0x9c, 0xf3, 0xdc, 0x35, 0xde, 0x1d, 0xaf, 0xa1, 0xe0, 0xd8, + 0x9c, 0xa4, 0x4f, 0xa2, 0xbd, 0xb5, 0x7e, 0xe4, 0x56, 0x4d, 0xb0, 0xa2, 0x40, 0x1d, 0xb8, 0xaf, + 0x5e, 0x21, 0xdc, 0xd8, 0x92, 0x6c, 0xdf, 0xac, 0xc5, 0xa6, 0x4a, 0x85, 0x53, 0x6c, 0x7c, 0x4d, + 0x85, 0x8c, 0xcc, 0x4f, 0x63, 0x9f, 0xd1, 0x1b, 0xcf, 0x25, 0xea, 0xa1, 0x53, 0xc2, 0x2b, 0x73, + 0xe8, 0x4b, 0x78, 0xa0, 0xec, 0x3d, 0x88, 0x1c, 0x87, 0x70, 0x2e, 0x5b, 0x57, 0x09, 0x2f, 0x07, + 0x1f, 0xf7, 0xa0, 0x94, 0x76, 0x55, 0xb4, 0x0d, 0xd0, 0xdf, 0xb7, 0x8e, 0x46, 0x03, 0xeb, 0xe2, + 0xa4, 0xa3, 0xdf, 0x43, 0x06, 0xec, 0x9c, 0x77, 0xb1, 0x35, 0xdc, 0x3f, 0x19, 0x1d, 0xf5, 0x06, + 0x56, 0xe7, 0x20, 0xc9, 0x68, 0xe8, 0x53, 0x78, 0xd4, 0x1a, 0xb6, 0x8f, 0x3b, 0xd6, 0xa8, 0xd5, + 0x1b, 0x9e, 0x1d, 0xc8, 0xf4, 0xd9, 0xfe, 0x69, 0x47, 0xcf, 0x3d, 0x6e, 0x41, 0x29, 0xdd, 0x14, + 0x04, 0x50, 0x54, 0xd3, 0xf4, 0x7b, 0xf1, 0x77, 0xaf, 0xf5, 0xba, 0xd3, 0xb6, 0x74, 0x0d, 0xe9, + 0x50, 0x3d, 0xeb, 0x59, 0xdd, 0xc3, 0x6e, 0x7b, 0xdf, 0xea, 0xf6, 0xce, 0xf4, 0x1c, 0xaa, 0x42, + 0xe9, 0xe8, 0x74, 0xbf, 0x3d, 0x3a, 0xee, 0x5c, 0xe8, 0xf9, 0xd6, 0x1b, 0xf8, 0xca, 0xa1, 0xd3, + 0x75, 0x2a, 0xd5, 0xd7, 0xde, 0xe7, 0xbe, 0x7e, 0xa5, 0xe6, 0xb5, 0xe5, 0xbc, 0x41, 0x92, 0x3b, + 0x7f, 0x66, 0xca, 0x67, 0xa9, 0xd9, 0x5e, 0x00, 0x2f, 0x8b, 0xb2, 0x21, 0x7f, 0xf7, 0x77, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x2e, 0x18, 0x4b, 0xe0, 0x21, 0x0c, 0x00, 0x00, } diff --git a/storage/internal/test/conformance/test.proto b/storage/internal/test/conformance/test.proto index d76ec856cad..2912070f883 100644 --- a/storage/internal/test/conformance/test.proto +++ b/storage/internal/test/conformance/test.proto @@ -95,20 +95,20 @@ message InstructionList { repeated string instructions = 1; } -// Test fixtures that are necessary for a method call. For example, +// Test resources that are necessary for a method call. For example, // storage.objects.get would require BUCKET and OBJECT. -enum Fixture { +enum Resource { BUCKET = 0; OBJECT = 1; NOTIFICATION = 2; HMAC_KEY = 3; } -// A particular storage API method and required fixtures in order to test it. +// A particular storage API method and required resources in order to test it. // Methods must be implemented in tests for each language. message Method { string name = 1; // e.g. storage.objects.get - repeated Fixture fixtures = 2; + repeated Resource resources = 2; } // Schema for a retry test, corresponding to a single scenario from the design From bd237cc12440c4c8fcc4ce547a5bd6268aa38136 Mon Sep 17 00:00:00 2001 From: Brenna Epp Date: Tue, 31 Aug 2021 17:51:35 -0500 Subject: [PATCH 16/25] fix to changes --- storage/conformance_test.go | 6 +- .../test/conformance/retry_tests.json | 102 +- storage/internal/test/conformance/test.pb.go | 1580 +++++++++++------ storage/internal/test/conformance/test.proto | 75 +- 4 files changed, 1155 insertions(+), 608 deletions(-) diff --git a/storage/conformance_test.go b/storage/conformance_test.go index ba1b1b89f58..afb137e7440 100644 --- a/storage/conformance_test.go +++ b/storage/conformance_test.go @@ -159,7 +159,7 @@ func TestRetryConformance(t *testing.T) { ctx := context.Background() // Create non-wrapped client to use for setup steps. - client, err := NewClient(ctx, option.WithEndpoint(host + "/storage/v1/")) + client, err := NewClient(ctx, option.WithEndpoint(host+"/storage/v1/")) if err != nil { t.Fatalf("storage.NewClient: %v", err) } @@ -265,7 +265,7 @@ func checkRetryTest(host, testID string) error { defer resp.Body.Close() testRes := struct { Instructions map[string][]string - Completed bool + Completed bool }{} if err := json.NewDecoder(resp.Body).Decode(&testRes); err != nil { return fmt.Errorf("decoding response: %v", err) @@ -321,7 +321,7 @@ func wrappedClient(host, testID string) (*Client, error) { c.Transport = wrappedTrans // Supply this client to storage.NewClient - client, err := NewClient(ctx, option.WithHTTPClient(&c), option.WithEndpoint(host + "/storage/v1/")) + client, err := NewClient(ctx, option.WithHTTPClient(&c), option.WithEndpoint(host+"/storage/v1/")) return client, err } diff --git a/storage/internal/test/conformance/retry_tests.json b/storage/internal/test/conformance/retry_tests.json index ee800d9f0d4..2e02ac115f3 100644 --- a/storage/internal/test/conformance/retry_tests.json +++ b/storage/internal/test/conformance/retry_tests.json @@ -2,92 +2,44 @@ "retryTests": [ { "id": 1, - "description": "always idempotent", + "description": "always_idempotent", "cases": [ { - "instructions": ["return-503", "return-503", "return-503"] + "instructions": ["return-503", "return-503"] }, { - "instructions": ["reset-connection", "reset-connection", "reset-connection"] + "instructions": ["return-reset-connection", "return-reset-connection"] }, { - "instructions": ["reset-connection", "return-503", "return-503"] + "instructions": ["return-reset-connection", "return-503"] } ], "methods": [ - {"name": "storage.buckets.get", "resources": ["BUCKET"]}, - {"name": "storage.objects.get", "resources": ["BUCKET", "OBJECT"]} + {"name": "storage.bucket_acl.get", "resources": ["BUCKET"]}, + {"name": "storage.bucket_acl.list", "resources": ["BUCKET"]}, + {"name": "storage.buckets.delete", "resources": ["BUCKET"]}, + {"name": "storage.buckets.get", "resources": ["BUCKET"]}, + {"name": "storage.buckets.getIamPolicy", "resources": ["BUCKET"]}, + {"name": "storage.buckets.insert", "resources": []}, + {"name": "storage.buckets.list", "resources": ["BUCKET"]}, + {"name": "storage.buckets.lockRetentionPolicy", "resources": ["BUCKET"]}, + {"name": "storage.buckets.testIamPermissions", "resources": ["BUCKET"]}, + {"name": "storage.default_object_acl.get", "resources": ["BUCKET"]}, + {"name": "storage.default_object_acl.list", "resources": ["BUCKET"]}, + {"name": "storage.hmacKey.delete", "resources": ["HMAC_KEY"]}, + {"name": "storage.hmacKey.get", "resources": ["HMAC_KEY"]}, + {"name": "storage.hmacKey.list", "resources": []}, + {"name": "storage.notifications.delete", "resources": ["BUCKET", "NOTIFICATION"]}, + {"name": "storage.notifications.get", "resources": ["BUCKET", "NOTIFICATION"]}, + {"name": "storage.notifications.list", "resources": ["BUCKET", "NOTIFICATION"]}, + {"name": "storage.object_acl.get", "resources": ["BUCKET", "OBJECT"]}, + {"name": "storage.object_acl.list", "resources": ["BUCKET", "OBJECT"]}, + {"name": "storage.objects.get", "resources": ["BUCKET", "OBJECT"]}, + {"name": "storage.objects.list", "resources": ["BUCKET", "OBJECT"]}, + {"name": "storage.serviceaccount.get", "resources": []} ], "preconditionProvided": false, "expectSuccess": true - }, - { - "id": 2, - "description": "conditionally idempotent, precondition present", - "cases": [ - { - "instructions": ["return-503", "return-503", "return-503"] - }, - { - "instructions": ["reset-connection", "reset-connection", "reset-connection"] - }, - { - "instructions": ["reset-connection", "return-503", "return-503"] - } - ], - "methods": [ - {"name": "storage.buckets.insert", "resources": []}, - {"name": "storage.buckets.update", "resources": ["BUCKET"]}, - {"name": "storage.objects.insert", "resources": ["BUCKET"]}, - {"name": "storage.objects.update", "resources": ["BUCKET", "OBJECT"]} - ], - "preconditionProvided": true, - "expectSuccess": true - }, - { - "id": 3, - "description": "conditionally idempotent, precondition not present", - "cases": [ - { - "instructions": ["return-503", "return-503", "return-503"] - }, - { - "instructions": ["reset-connection", "reset-connection", "reset-connection"] - }, - { - "instructions": ["reset-connection", "return-503", "return-503"] - } - ], - "methods": [ - {"name": "storage.buckets.insert", "resources": []}, - {"name": "storage.buckets.update", "resources": ["BUCKET"]}, - {"name": "storage.objects.insert", "resources": ["BUCKET"]}, - {"name": "storage.objects.update", "resources": ["BUCKET", "OBJECT"]} - ], - "preconditionProvided": false, - "expectSuccess": false - }, - { - "id": 6, - "description": "non-retryable errors", - "cases": [ - { - "instructions": ["return-400", "return-400", "return-400"] - }, - { - "instructions": ["return-401", "return-401", "return-401"] - } - ], - "methods": [ - {"name": "storage.objects.get", "resources": ["BUCKET", "OBJECT"]}, - {"name": "storage.buckets.get", "resources": ["BUCKET"]}, - {"name": "storage.buckets.insert", "resources": []}, - {"name": "storage.buckets.update", "resources": ["BUCKET"]}, - {"name": "storage.objects.insert", "resources": ["BUCKET"]}, - {"name": "storage.objects.update", "resources": ["BUCKET", "OBJECT"]} - ], - "preconditionProvided": false, - "expectSuccess": false } ] -} \ No newline at end of file +} diff --git a/storage/internal/test/conformance/test.pb.go b/storage/internal/test/conformance/test.pb.go index ffc3e59746a..5d42e4b32ed 100644 --- a/storage/internal/test/conformance/test.pb.go +++ b/storage/internal/test/conformance/test.pb.go @@ -1,25 +1,39 @@ +// Copyright 2019, Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + // Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc v3.17.3 // source: test.proto -package google_cloud_conformance_storage_v1 +package v1 import ( - fmt "fmt" - proto "github.com/golang/protobuf/proto" - timestamp "github.com/golang/protobuf/ptypes/timestamp" - math "math" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" ) -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) type UrlStyle int32 @@ -29,24 +43,45 @@ const ( UrlStyle_BUCKET_BOUND_HOSTNAME UrlStyle = 2 ) -var UrlStyle_name = map[int32]string{ - 0: "PATH_STYLE", - 1: "VIRTUAL_HOSTED_STYLE", - 2: "BUCKET_BOUND_HOSTNAME", -} +// Enum value maps for UrlStyle. +var ( + UrlStyle_name = map[int32]string{ + 0: "PATH_STYLE", + 1: "VIRTUAL_HOSTED_STYLE", + 2: "BUCKET_BOUND_HOSTNAME", + } + UrlStyle_value = map[string]int32{ + "PATH_STYLE": 0, + "VIRTUAL_HOSTED_STYLE": 1, + "BUCKET_BOUND_HOSTNAME": 2, + } +) -var UrlStyle_value = map[string]int32{ - "PATH_STYLE": 0, - "VIRTUAL_HOSTED_STYLE": 1, - "BUCKET_BOUND_HOSTNAME": 2, +func (x UrlStyle) Enum() *UrlStyle { + p := new(UrlStyle) + *p = x + return p } func (x UrlStyle) String() string { - return proto.EnumName(UrlStyle_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (UrlStyle) Descriptor() protoreflect.EnumDescriptor { + return file_test_proto_enumTypes[0].Descriptor() } +func (UrlStyle) Type() protoreflect.EnumType { + return &file_test_proto_enumTypes[0] +} + +func (x UrlStyle) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use UrlStyle.Descriptor instead. func (UrlStyle) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_c161fcfdc0c3ff1e, []int{0} + return file_test_proto_rawDescGZIP(), []int{0} } // Test resources that are necessary for a method call. For example, @@ -60,529 +95,662 @@ const ( Resource_HMAC_KEY Resource = 3 ) -var Resource_name = map[int32]string{ - 0: "BUCKET", - 1: "OBJECT", - 2: "NOTIFICATION", - 3: "HMAC_KEY", -} +// Enum value maps for Resource. +var ( + Resource_name = map[int32]string{ + 0: "BUCKET", + 1: "OBJECT", + 2: "NOTIFICATION", + 3: "HMAC_KEY", + } + Resource_value = map[string]int32{ + "BUCKET": 0, + "OBJECT": 1, + "NOTIFICATION": 2, + "HMAC_KEY": 3, + } +) -var Resource_value = map[string]int32{ - "BUCKET": 0, - "OBJECT": 1, - "NOTIFICATION": 2, - "HMAC_KEY": 3, +func (x Resource) Enum() *Resource { + p := new(Resource) + *p = x + return p } func (x Resource) String() string { - return proto.EnumName(Resource_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } -func (Resource) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_c161fcfdc0c3ff1e, []int{1} +func (Resource) Descriptor() protoreflect.EnumDescriptor { + return file_test_proto_enumTypes[1].Descriptor() } -type TestFile struct { - SigningV4Tests []*SigningV4Test `protobuf:"bytes,1,rep,name=signing_v4_tests,json=signingV4Tests,proto3" json:"signing_v4_tests,omitempty"` - PostPolicyV4Tests []*PostPolicyV4Test `protobuf:"bytes,2,rep,name=post_policy_v4_tests,json=postPolicyV4Tests,proto3" json:"post_policy_v4_tests,omitempty"` - RetryTests []*RetryTest `protobuf:"bytes,3,rep,name=retry_tests,json=retryTests,proto3" json:"retry_tests,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` +func (Resource) Type() protoreflect.EnumType { + return &file_test_proto_enumTypes[1] } -func (m *TestFile) Reset() { *m = TestFile{} } -func (m *TestFile) String() string { return proto.CompactTextString(m) } -func (*TestFile) ProtoMessage() {} -func (*TestFile) Descriptor() ([]byte, []int) { - return fileDescriptor_c161fcfdc0c3ff1e, []int{0} +func (x Resource) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) } -func (m *TestFile) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_TestFile.Unmarshal(m, b) +// Deprecated: Use Resource.Descriptor instead. +func (Resource) EnumDescriptor() ([]byte, []int) { + return file_test_proto_rawDescGZIP(), []int{1} } -func (m *TestFile) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_TestFile.Marshal(b, m, deterministic) + +type TestFile struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SigningV4Tests []*SigningV4Test `protobuf:"bytes,1,rep,name=signing_v4_tests,json=signingV4Tests,proto3" json:"signing_v4_tests,omitempty"` + PostPolicyV4Tests []*PostPolicyV4Test `protobuf:"bytes,2,rep,name=post_policy_v4_tests,json=postPolicyV4Tests,proto3" json:"post_policy_v4_tests,omitempty"` + RetryTests []*RetryTest `protobuf:"bytes,3,rep,name=retry_tests,json=retryTests,proto3" json:"retry_tests,omitempty"` } -func (m *TestFile) XXX_Merge(src proto.Message) { - xxx_messageInfo_TestFile.Merge(m, src) + +func (x *TestFile) Reset() { + *x = TestFile{} + if protoimpl.UnsafeEnabled { + mi := &file_test_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *TestFile) XXX_Size() int { - return xxx_messageInfo_TestFile.Size(m) + +func (x *TestFile) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *TestFile) XXX_DiscardUnknown() { - xxx_messageInfo_TestFile.DiscardUnknown(m) + +func (*TestFile) ProtoMessage() {} + +func (x *TestFile) ProtoReflect() protoreflect.Message { + mi := &file_test_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_TestFile proto.InternalMessageInfo +// Deprecated: Use TestFile.ProtoReflect.Descriptor instead. +func (*TestFile) Descriptor() ([]byte, []int) { + return file_test_proto_rawDescGZIP(), []int{0} +} -func (m *TestFile) GetSigningV4Tests() []*SigningV4Test { - if m != nil { - return m.SigningV4Tests +func (x *TestFile) GetSigningV4Tests() []*SigningV4Test { + if x != nil { + return x.SigningV4Tests } return nil } -func (m *TestFile) GetPostPolicyV4Tests() []*PostPolicyV4Test { - if m != nil { - return m.PostPolicyV4Tests +func (x *TestFile) GetPostPolicyV4Tests() []*PostPolicyV4Test { + if x != nil { + return x.PostPolicyV4Tests } return nil } -func (m *TestFile) GetRetryTests() []*RetryTest { - if m != nil { - return m.RetryTests +func (x *TestFile) GetRetryTests() []*RetryTest { + if x != nil { + return x.RetryTests } return nil } type SigningV4Test struct { - FileName string `protobuf:"bytes,1,opt,name=fileName,proto3" json:"fileName,omitempty"` - Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` - Bucket string `protobuf:"bytes,3,opt,name=bucket,proto3" json:"bucket,omitempty"` - Object string `protobuf:"bytes,4,opt,name=object,proto3" json:"object,omitempty"` - Method string `protobuf:"bytes,5,opt,name=method,proto3" json:"method,omitempty"` - Expiration int64 `protobuf:"varint,6,opt,name=expiration,proto3" json:"expiration,omitempty"` - Timestamp *timestamp.Timestamp `protobuf:"bytes,7,opt,name=timestamp,proto3" json:"timestamp,omitempty"` - ExpectedUrl string `protobuf:"bytes,8,opt,name=expectedUrl,proto3" json:"expectedUrl,omitempty"` - Headers map[string]string `protobuf:"bytes,9,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - QueryParameters map[string]string `protobuf:"bytes,10,rep,name=query_parameters,json=queryParameters,proto3" json:"query_parameters,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - Scheme string `protobuf:"bytes,11,opt,name=scheme,proto3" json:"scheme,omitempty"` - UrlStyle UrlStyle `protobuf:"varint,12,opt,name=urlStyle,proto3,enum=google.cloud.conformance.storage.v1.UrlStyle" json:"urlStyle,omitempty"` - BucketBoundHostname string `protobuf:"bytes,13,opt,name=bucketBoundHostname,proto3" json:"bucketBoundHostname,omitempty"` - ExpectedCanonicalRequest string `protobuf:"bytes,14,opt,name=expectedCanonicalRequest,proto3" json:"expectedCanonicalRequest,omitempty"` - ExpectedStringToSign string `protobuf:"bytes,15,opt,name=expectedStringToSign,proto3" json:"expectedStringToSign,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *SigningV4Test) Reset() { *m = SigningV4Test{} } -func (m *SigningV4Test) String() string { return proto.CompactTextString(m) } -func (*SigningV4Test) ProtoMessage() {} -func (*SigningV4Test) Descriptor() ([]byte, []int) { - return fileDescriptor_c161fcfdc0c3ff1e, []int{1} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + FileName string `protobuf:"bytes,1,opt,name=fileName,proto3" json:"fileName,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + Bucket string `protobuf:"bytes,3,opt,name=bucket,proto3" json:"bucket,omitempty"` + Object string `protobuf:"bytes,4,opt,name=object,proto3" json:"object,omitempty"` + Method string `protobuf:"bytes,5,opt,name=method,proto3" json:"method,omitempty"` + Expiration int64 `protobuf:"varint,6,opt,name=expiration,proto3" json:"expiration,omitempty"` + Timestamp *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + ExpectedUrl string `protobuf:"bytes,8,opt,name=expectedUrl,proto3" json:"expectedUrl,omitempty"` + Headers map[string]string `protobuf:"bytes,9,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + QueryParameters map[string]string `protobuf:"bytes,10,rep,name=query_parameters,json=queryParameters,proto3" json:"query_parameters,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Scheme string `protobuf:"bytes,11,opt,name=scheme,proto3" json:"scheme,omitempty"` + UrlStyle UrlStyle `protobuf:"varint,12,opt,name=urlStyle,proto3,enum=google.cloud.conformance.storage.v1.UrlStyle" json:"urlStyle,omitempty"` + BucketBoundHostname string `protobuf:"bytes,13,opt,name=bucketBoundHostname,proto3" json:"bucketBoundHostname,omitempty"` + ExpectedCanonicalRequest string `protobuf:"bytes,14,opt,name=expectedCanonicalRequest,proto3" json:"expectedCanonicalRequest,omitempty"` + ExpectedStringToSign string `protobuf:"bytes,15,opt,name=expectedStringToSign,proto3" json:"expectedStringToSign,omitempty"` +} + +func (x *SigningV4Test) Reset() { + *x = SigningV4Test{} + if protoimpl.UnsafeEnabled { + mi := &file_test_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *SigningV4Test) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_SigningV4Test.Unmarshal(m, b) -} -func (m *SigningV4Test) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_SigningV4Test.Marshal(b, m, deterministic) -} -func (m *SigningV4Test) XXX_Merge(src proto.Message) { - xxx_messageInfo_SigningV4Test.Merge(m, src) -} -func (m *SigningV4Test) XXX_Size() int { - return xxx_messageInfo_SigningV4Test.Size(m) +func (x *SigningV4Test) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *SigningV4Test) XXX_DiscardUnknown() { - xxx_messageInfo_SigningV4Test.DiscardUnknown(m) + +func (*SigningV4Test) ProtoMessage() {} + +func (x *SigningV4Test) ProtoReflect() protoreflect.Message { + mi := &file_test_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_SigningV4Test proto.InternalMessageInfo +// Deprecated: Use SigningV4Test.ProtoReflect.Descriptor instead. +func (*SigningV4Test) Descriptor() ([]byte, []int) { + return file_test_proto_rawDescGZIP(), []int{1} +} -func (m *SigningV4Test) GetFileName() string { - if m != nil { - return m.FileName +func (x *SigningV4Test) GetFileName() string { + if x != nil { + return x.FileName } return "" } -func (m *SigningV4Test) GetDescription() string { - if m != nil { - return m.Description +func (x *SigningV4Test) GetDescription() string { + if x != nil { + return x.Description } return "" } -func (m *SigningV4Test) GetBucket() string { - if m != nil { - return m.Bucket +func (x *SigningV4Test) GetBucket() string { + if x != nil { + return x.Bucket } return "" } -func (m *SigningV4Test) GetObject() string { - if m != nil { - return m.Object +func (x *SigningV4Test) GetObject() string { + if x != nil { + return x.Object } return "" } -func (m *SigningV4Test) GetMethod() string { - if m != nil { - return m.Method +func (x *SigningV4Test) GetMethod() string { + if x != nil { + return x.Method } return "" } -func (m *SigningV4Test) GetExpiration() int64 { - if m != nil { - return m.Expiration +func (x *SigningV4Test) GetExpiration() int64 { + if x != nil { + return x.Expiration } return 0 } -func (m *SigningV4Test) GetTimestamp() *timestamp.Timestamp { - if m != nil { - return m.Timestamp +func (x *SigningV4Test) GetTimestamp() *timestamppb.Timestamp { + if x != nil { + return x.Timestamp } return nil } -func (m *SigningV4Test) GetExpectedUrl() string { - if m != nil { - return m.ExpectedUrl +func (x *SigningV4Test) GetExpectedUrl() string { + if x != nil { + return x.ExpectedUrl } return "" } -func (m *SigningV4Test) GetHeaders() map[string]string { - if m != nil { - return m.Headers +func (x *SigningV4Test) GetHeaders() map[string]string { + if x != nil { + return x.Headers } return nil } -func (m *SigningV4Test) GetQueryParameters() map[string]string { - if m != nil { - return m.QueryParameters +func (x *SigningV4Test) GetQueryParameters() map[string]string { + if x != nil { + return x.QueryParameters } return nil } -func (m *SigningV4Test) GetScheme() string { - if m != nil { - return m.Scheme +func (x *SigningV4Test) GetScheme() string { + if x != nil { + return x.Scheme } return "" } -func (m *SigningV4Test) GetUrlStyle() UrlStyle { - if m != nil { - return m.UrlStyle +func (x *SigningV4Test) GetUrlStyle() UrlStyle { + if x != nil { + return x.UrlStyle } return UrlStyle_PATH_STYLE } -func (m *SigningV4Test) GetBucketBoundHostname() string { - if m != nil { - return m.BucketBoundHostname +func (x *SigningV4Test) GetBucketBoundHostname() string { + if x != nil { + return x.BucketBoundHostname } return "" } -func (m *SigningV4Test) GetExpectedCanonicalRequest() string { - if m != nil { - return m.ExpectedCanonicalRequest +func (x *SigningV4Test) GetExpectedCanonicalRequest() string { + if x != nil { + return x.ExpectedCanonicalRequest } return "" } -func (m *SigningV4Test) GetExpectedStringToSign() string { - if m != nil { - return m.ExpectedStringToSign +func (x *SigningV4Test) GetExpectedStringToSign() string { + if x != nil { + return x.ExpectedStringToSign } return "" } type ConditionalMatches struct { - Expression []string `protobuf:"bytes,1,rep,name=expression,proto3" json:"expression,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *ConditionalMatches) Reset() { *m = ConditionalMatches{} } -func (m *ConditionalMatches) String() string { return proto.CompactTextString(m) } -func (*ConditionalMatches) ProtoMessage() {} -func (*ConditionalMatches) Descriptor() ([]byte, []int) { - return fileDescriptor_c161fcfdc0c3ff1e, []int{2} + Expression []string `protobuf:"bytes,1,rep,name=expression,proto3" json:"expression,omitempty"` } -func (m *ConditionalMatches) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ConditionalMatches.Unmarshal(m, b) -} -func (m *ConditionalMatches) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ConditionalMatches.Marshal(b, m, deterministic) -} -func (m *ConditionalMatches) XXX_Merge(src proto.Message) { - xxx_messageInfo_ConditionalMatches.Merge(m, src) +func (x *ConditionalMatches) Reset() { + *x = ConditionalMatches{} + if protoimpl.UnsafeEnabled { + mi := &file_test_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *ConditionalMatches) XXX_Size() int { - return xxx_messageInfo_ConditionalMatches.Size(m) + +func (x *ConditionalMatches) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *ConditionalMatches) XXX_DiscardUnknown() { - xxx_messageInfo_ConditionalMatches.DiscardUnknown(m) + +func (*ConditionalMatches) ProtoMessage() {} + +func (x *ConditionalMatches) ProtoReflect() protoreflect.Message { + mi := &file_test_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_ConditionalMatches proto.InternalMessageInfo +// Deprecated: Use ConditionalMatches.ProtoReflect.Descriptor instead. +func (*ConditionalMatches) Descriptor() ([]byte, []int) { + return file_test_proto_rawDescGZIP(), []int{2} +} -func (m *ConditionalMatches) GetExpression() []string { - if m != nil { - return m.Expression +func (x *ConditionalMatches) GetExpression() []string { + if x != nil { + return x.Expression } return nil } type PolicyConditions struct { - ContentLengthRange []int32 `protobuf:"varint,1,rep,packed,name=contentLengthRange,proto3" json:"contentLengthRange,omitempty"` - StartsWith []string `protobuf:"bytes,2,rep,name=startsWith,proto3" json:"startsWith,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *PolicyConditions) Reset() { *m = PolicyConditions{} } -func (m *PolicyConditions) String() string { return proto.CompactTextString(m) } -func (*PolicyConditions) ProtoMessage() {} -func (*PolicyConditions) Descriptor() ([]byte, []int) { - return fileDescriptor_c161fcfdc0c3ff1e, []int{3} + ContentLengthRange []int32 `protobuf:"varint,1,rep,packed,name=contentLengthRange,proto3" json:"contentLengthRange,omitempty"` + StartsWith []string `protobuf:"bytes,2,rep,name=startsWith,proto3" json:"startsWith,omitempty"` } -func (m *PolicyConditions) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PolicyConditions.Unmarshal(m, b) -} -func (m *PolicyConditions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PolicyConditions.Marshal(b, m, deterministic) -} -func (m *PolicyConditions) XXX_Merge(src proto.Message) { - xxx_messageInfo_PolicyConditions.Merge(m, src) +func (x *PolicyConditions) Reset() { + *x = PolicyConditions{} + if protoimpl.UnsafeEnabled { + mi := &file_test_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *PolicyConditions) XXX_Size() int { - return xxx_messageInfo_PolicyConditions.Size(m) + +func (x *PolicyConditions) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *PolicyConditions) XXX_DiscardUnknown() { - xxx_messageInfo_PolicyConditions.DiscardUnknown(m) + +func (*PolicyConditions) ProtoMessage() {} + +func (x *PolicyConditions) ProtoReflect() protoreflect.Message { + mi := &file_test_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_PolicyConditions proto.InternalMessageInfo +// Deprecated: Use PolicyConditions.ProtoReflect.Descriptor instead. +func (*PolicyConditions) Descriptor() ([]byte, []int) { + return file_test_proto_rawDescGZIP(), []int{3} +} -func (m *PolicyConditions) GetContentLengthRange() []int32 { - if m != nil { - return m.ContentLengthRange +func (x *PolicyConditions) GetContentLengthRange() []int32 { + if x != nil { + return x.ContentLengthRange } return nil } -func (m *PolicyConditions) GetStartsWith() []string { - if m != nil { - return m.StartsWith +func (x *PolicyConditions) GetStartsWith() []string { + if x != nil { + return x.StartsWith } return nil } type PolicyInput struct { - Scheme string `protobuf:"bytes,1,opt,name=scheme,proto3" json:"scheme,omitempty"` - UrlStyle UrlStyle `protobuf:"varint,2,opt,name=urlStyle,proto3,enum=google.cloud.conformance.storage.v1.UrlStyle" json:"urlStyle,omitempty"` - BucketBoundHostname string `protobuf:"bytes,3,opt,name=bucketBoundHostname,proto3" json:"bucketBoundHostname,omitempty"` - Bucket string `protobuf:"bytes,4,opt,name=bucket,proto3" json:"bucket,omitempty"` - Object string `protobuf:"bytes,5,opt,name=object,proto3" json:"object,omitempty"` - Expiration int32 `protobuf:"varint,6,opt,name=expiration,proto3" json:"expiration,omitempty"` - Timestamp *timestamp.Timestamp `protobuf:"bytes,7,opt,name=timestamp,proto3" json:"timestamp,omitempty"` - Fields map[string]string `protobuf:"bytes,8,rep,name=fields,proto3" json:"fields,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - Conditions *PolicyConditions `protobuf:"bytes,9,opt,name=conditions,proto3" json:"conditions,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *PolicyInput) Reset() { *m = PolicyInput{} } -func (m *PolicyInput) String() string { return proto.CompactTextString(m) } -func (*PolicyInput) ProtoMessage() {} -func (*PolicyInput) Descriptor() ([]byte, []int) { - return fileDescriptor_c161fcfdc0c3ff1e, []int{4} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // http or https + Scheme string `protobuf:"bytes,1,opt,name=scheme,proto3" json:"scheme,omitempty"` + UrlStyle UrlStyle `protobuf:"varint,2,opt,name=urlStyle,proto3,enum=google.cloud.conformance.storage.v1.UrlStyle" json:"urlStyle,omitempty"` + BucketBoundHostname string `protobuf:"bytes,3,opt,name=bucketBoundHostname,proto3" json:"bucketBoundHostname,omitempty"` + Bucket string `protobuf:"bytes,4,opt,name=bucket,proto3" json:"bucket,omitempty"` + Object string `protobuf:"bytes,5,opt,name=object,proto3" json:"object,omitempty"` + Expiration int32 `protobuf:"varint,6,opt,name=expiration,proto3" json:"expiration,omitempty"` + Timestamp *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + // + //fields with strict equivalence which are added into + //PolicyOutput.expectedDecodedPolicy to generate the + //signature. + //Expectations + //E.1: Order them in lexigraphical order so it's the + //signature can be verified across different language + //implementations. + Fields map[string]string `protobuf:"bytes,8,rep,name=fields,proto3" json:"fields,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Conditions *PolicyConditions `protobuf:"bytes,9,opt,name=conditions,proto3" json:"conditions,omitempty"` +} + +func (x *PolicyInput) Reset() { + *x = PolicyInput{} + if protoimpl.UnsafeEnabled { + mi := &file_test_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *PolicyInput) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PolicyInput.Unmarshal(m, b) -} -func (m *PolicyInput) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PolicyInput.Marshal(b, m, deterministic) -} -func (m *PolicyInput) XXX_Merge(src proto.Message) { - xxx_messageInfo_PolicyInput.Merge(m, src) +func (x *PolicyInput) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *PolicyInput) XXX_Size() int { - return xxx_messageInfo_PolicyInput.Size(m) -} -func (m *PolicyInput) XXX_DiscardUnknown() { - xxx_messageInfo_PolicyInput.DiscardUnknown(m) + +func (*PolicyInput) ProtoMessage() {} + +func (x *PolicyInput) ProtoReflect() protoreflect.Message { + mi := &file_test_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_PolicyInput proto.InternalMessageInfo +// Deprecated: Use PolicyInput.ProtoReflect.Descriptor instead. +func (*PolicyInput) Descriptor() ([]byte, []int) { + return file_test_proto_rawDescGZIP(), []int{4} +} -func (m *PolicyInput) GetScheme() string { - if m != nil { - return m.Scheme +func (x *PolicyInput) GetScheme() string { + if x != nil { + return x.Scheme } return "" } -func (m *PolicyInput) GetUrlStyle() UrlStyle { - if m != nil { - return m.UrlStyle +func (x *PolicyInput) GetUrlStyle() UrlStyle { + if x != nil { + return x.UrlStyle } return UrlStyle_PATH_STYLE } -func (m *PolicyInput) GetBucketBoundHostname() string { - if m != nil { - return m.BucketBoundHostname +func (x *PolicyInput) GetBucketBoundHostname() string { + if x != nil { + return x.BucketBoundHostname } return "" } -func (m *PolicyInput) GetBucket() string { - if m != nil { - return m.Bucket +func (x *PolicyInput) GetBucket() string { + if x != nil { + return x.Bucket } return "" } -func (m *PolicyInput) GetObject() string { - if m != nil { - return m.Object +func (x *PolicyInput) GetObject() string { + if x != nil { + return x.Object } return "" } -func (m *PolicyInput) GetExpiration() int32 { - if m != nil { - return m.Expiration +func (x *PolicyInput) GetExpiration() int32 { + if x != nil { + return x.Expiration } return 0 } -func (m *PolicyInput) GetTimestamp() *timestamp.Timestamp { - if m != nil { - return m.Timestamp +func (x *PolicyInput) GetTimestamp() *timestamppb.Timestamp { + if x != nil { + return x.Timestamp } return nil } -func (m *PolicyInput) GetFields() map[string]string { - if m != nil { - return m.Fields +func (x *PolicyInput) GetFields() map[string]string { + if x != nil { + return x.Fields } return nil } -func (m *PolicyInput) GetConditions() *PolicyConditions { - if m != nil { - return m.Conditions +func (x *PolicyInput) GetConditions() *PolicyConditions { + if x != nil { + return x.Conditions } return nil } type PolicyOutput struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"` Fields map[string]string `protobuf:"bytes,2,rep,name=fields,proto3" json:"fields,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` ExpectedDecodedPolicy string `protobuf:"bytes,3,opt,name=expectedDecodedPolicy,proto3" json:"expectedDecodedPolicy,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` } -func (m *PolicyOutput) Reset() { *m = PolicyOutput{} } -func (m *PolicyOutput) String() string { return proto.CompactTextString(m) } -func (*PolicyOutput) ProtoMessage() {} -func (*PolicyOutput) Descriptor() ([]byte, []int) { - return fileDescriptor_c161fcfdc0c3ff1e, []int{5} +func (x *PolicyOutput) Reset() { + *x = PolicyOutput{} + if protoimpl.UnsafeEnabled { + mi := &file_test_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *PolicyOutput) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PolicyOutput.Unmarshal(m, b) -} -func (m *PolicyOutput) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PolicyOutput.Marshal(b, m, deterministic) -} -func (m *PolicyOutput) XXX_Merge(src proto.Message) { - xxx_messageInfo_PolicyOutput.Merge(m, src) +func (x *PolicyOutput) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *PolicyOutput) XXX_Size() int { - return xxx_messageInfo_PolicyOutput.Size(m) -} -func (m *PolicyOutput) XXX_DiscardUnknown() { - xxx_messageInfo_PolicyOutput.DiscardUnknown(m) + +func (*PolicyOutput) ProtoMessage() {} + +func (x *PolicyOutput) ProtoReflect() protoreflect.Message { + mi := &file_test_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_PolicyOutput proto.InternalMessageInfo +// Deprecated: Use PolicyOutput.ProtoReflect.Descriptor instead. +func (*PolicyOutput) Descriptor() ([]byte, []int) { + return file_test_proto_rawDescGZIP(), []int{5} +} -func (m *PolicyOutput) GetUrl() string { - if m != nil { - return m.Url +func (x *PolicyOutput) GetUrl() string { + if x != nil { + return x.Url } return "" } -func (m *PolicyOutput) GetFields() map[string]string { - if m != nil { - return m.Fields +func (x *PolicyOutput) GetFields() map[string]string { + if x != nil { + return x.Fields } return nil } -func (m *PolicyOutput) GetExpectedDecodedPolicy() string { - if m != nil { - return m.ExpectedDecodedPolicy +func (x *PolicyOutput) GetExpectedDecodedPolicy() string { + if x != nil { + return x.ExpectedDecodedPolicy } return "" } type PostPolicyV4Test struct { - Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` - PolicyInput *PolicyInput `protobuf:"bytes,2,opt,name=policyInput,proto3" json:"policyInput,omitempty"` - PolicyOutput *PolicyOutput `protobuf:"bytes,3,opt,name=policyOutput,proto3" json:"policyOutput,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` + PolicyInput *PolicyInput `protobuf:"bytes,2,opt,name=policyInput,proto3" json:"policyInput,omitempty"` + PolicyOutput *PolicyOutput `protobuf:"bytes,3,opt,name=policyOutput,proto3" json:"policyOutput,omitempty"` } -func (m *PostPolicyV4Test) Reset() { *m = PostPolicyV4Test{} } -func (m *PostPolicyV4Test) String() string { return proto.CompactTextString(m) } -func (*PostPolicyV4Test) ProtoMessage() {} -func (*PostPolicyV4Test) Descriptor() ([]byte, []int) { - return fileDescriptor_c161fcfdc0c3ff1e, []int{6} +func (x *PostPolicyV4Test) Reset() { + *x = PostPolicyV4Test{} + if protoimpl.UnsafeEnabled { + mi := &file_test_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *PostPolicyV4Test) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PostPolicyV4Test.Unmarshal(m, b) +func (x *PostPolicyV4Test) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *PostPolicyV4Test) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PostPolicyV4Test.Marshal(b, m, deterministic) + +func (*PostPolicyV4Test) ProtoMessage() {} + +func (x *PostPolicyV4Test) ProtoReflect() protoreflect.Message { + mi := &file_test_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PostPolicyV4Test.ProtoReflect.Descriptor instead. +func (*PostPolicyV4Test) Descriptor() ([]byte, []int) { + return file_test_proto_rawDescGZIP(), []int{6} } -func (m *PostPolicyV4Test) XXX_Merge(src proto.Message) { - xxx_messageInfo_PostPolicyV4Test.Merge(m, src) + +func (x *PostPolicyV4Test) GetDescription() string { + if x != nil { + return x.Description + } + return "" } -func (m *PostPolicyV4Test) XXX_Size() int { - return xxx_messageInfo_PostPolicyV4Test.Size(m) + +func (x *PostPolicyV4Test) GetPolicyInput() *PolicyInput { + if x != nil { + return x.PolicyInput + } + return nil } -func (m *PostPolicyV4Test) XXX_DiscardUnknown() { - xxx_messageInfo_PostPolicyV4Test.DiscardUnknown(m) + +func (x *PostPolicyV4Test) GetPolicyOutput() *PolicyOutput { + if x != nil { + return x.PolicyOutput + } + return nil } -var xxx_messageInfo_PostPolicyV4Test proto.InternalMessageInfo +type RetryTests struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *PostPolicyV4Test) GetDescription() string { - if m != nil { - return m.Description + RetryTests []*RetryTest `protobuf:"bytes,1,rep,name=retryTests,proto3" json:"retryTests,omitempty"` +} + +func (x *RetryTests) Reset() { + *x = RetryTests{} + if protoimpl.UnsafeEnabled { + mi := &file_test_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } - return "" } -func (m *PostPolicyV4Test) GetPolicyInput() *PolicyInput { - if m != nil { - return m.PolicyInput +func (x *RetryTests) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RetryTests) ProtoMessage() {} + +func (x *RetryTests) ProtoReflect() protoreflect.Message { + mi := &file_test_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms } - return nil + return mi.MessageOf(x) +} + +// Deprecated: Use RetryTests.ProtoReflect.Descriptor instead. +func (*RetryTests) Descriptor() ([]byte, []int) { + return file_test_proto_rawDescGZIP(), []int{7} } -func (m *PostPolicyV4Test) GetPolicyOutput() *PolicyOutput { - if m != nil { - return m.PolicyOutput +func (x *RetryTests) GetRetryTests() []*RetryTest { + if x != nil { + return x.RetryTests } return nil } @@ -590,40 +758,48 @@ func (m *PostPolicyV4Test) GetPolicyOutput() *PolicyOutput { // A list of instructions to send as headers to the GCS emulator. Each // instruction will force a specified failure for that request. type InstructionList struct { - Instructions []string `protobuf:"bytes,1,rep,name=instructions,proto3" json:"instructions,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *InstructionList) Reset() { *m = InstructionList{} } -func (m *InstructionList) String() string { return proto.CompactTextString(m) } -func (*InstructionList) ProtoMessage() {} -func (*InstructionList) Descriptor() ([]byte, []int) { - return fileDescriptor_c161fcfdc0c3ff1e, []int{7} + Instructions []string `protobuf:"bytes,1,rep,name=instructions,proto3" json:"instructions,omitempty"` } -func (m *InstructionList) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_InstructionList.Unmarshal(m, b) -} -func (m *InstructionList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_InstructionList.Marshal(b, m, deterministic) -} -func (m *InstructionList) XXX_Merge(src proto.Message) { - xxx_messageInfo_InstructionList.Merge(m, src) +func (x *InstructionList) Reset() { + *x = InstructionList{} + if protoimpl.UnsafeEnabled { + mi := &file_test_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *InstructionList) XXX_Size() int { - return xxx_messageInfo_InstructionList.Size(m) + +func (x *InstructionList) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *InstructionList) XXX_DiscardUnknown() { - xxx_messageInfo_InstructionList.DiscardUnknown(m) + +func (*InstructionList) ProtoMessage() {} + +func (x *InstructionList) ProtoReflect() protoreflect.Message { + mi := &file_test_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_InstructionList proto.InternalMessageInfo +// Deprecated: Use InstructionList.ProtoReflect.Descriptor instead. +func (*InstructionList) Descriptor() ([]byte, []int) { + return file_test_proto_rawDescGZIP(), []int{8} +} -func (m *InstructionList) GetInstructions() []string { - if m != nil { - return m.Instructions +func (x *InstructionList) GetInstructions() []string { + if x != nil { + return x.Instructions } return nil } @@ -631,48 +807,56 @@ func (m *InstructionList) GetInstructions() []string { // A particular storage API method and required resources in order to test it. // Methods must be implemented in tests for each language. type Method struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Resources []Resource `protobuf:"varint,2,rep,packed,name=resources,proto3,enum=google.cloud.conformance.storage.v1.Resource" json:"resources,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *Method) Reset() { *m = Method{} } -func (m *Method) String() string { return proto.CompactTextString(m) } -func (*Method) ProtoMessage() {} -func (*Method) Descriptor() ([]byte, []int) { - return fileDescriptor_c161fcfdc0c3ff1e, []int{8} + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // e.g. storage.objects.get + Resources []Resource `protobuf:"varint,2,rep,packed,name=resources,proto3,enum=google.cloud.conformance.storage.v1.Resource" json:"resources,omitempty"` } -func (m *Method) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Method.Unmarshal(m, b) -} -func (m *Method) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Method.Marshal(b, m, deterministic) -} -func (m *Method) XXX_Merge(src proto.Message) { - xxx_messageInfo_Method.Merge(m, src) +func (x *Method) Reset() { + *x = Method{} + if protoimpl.UnsafeEnabled { + mi := &file_test_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *Method) XXX_Size() int { - return xxx_messageInfo_Method.Size(m) + +func (x *Method) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *Method) XXX_DiscardUnknown() { - xxx_messageInfo_Method.DiscardUnknown(m) + +func (*Method) ProtoMessage() {} + +func (x *Method) ProtoReflect() protoreflect.Message { + mi := &file_test_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_Method proto.InternalMessageInfo +// Deprecated: Use Method.ProtoReflect.Descriptor instead. +func (*Method) Descriptor() ([]byte, []int) { + return file_test_proto_rawDescGZIP(), []int{9} +} -func (m *Method) GetName() string { - if m != nil { - return m.Name +func (x *Method) GetName() string { + if x != nil { + return x.Name } return "" } -func (m *Method) GetResources() []Resource { - if m != nil { - return m.Resources +func (x *Method) GetResources() []Resource { + if x != nil { + return x.Resources } return nil } @@ -680,10 +864,15 @@ func (m *Method) GetResources() []Resource { // Schema for a retry test, corresponding to a single scenario from the design // doc. type RetryTest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Scenario number Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` // Human-readable description of the test case. Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` - // List of emulator instructions. + // list of emulator instruction sets. Cases []*InstructionList `protobuf:"bytes,3,rep,name=cases,proto3" json:"cases,omitempty"` // List of API methods to be tested. Methods []*Method `protobuf:"bytes,4,rep,name=methods,proto3" json:"methods,omitempty"` @@ -692,170 +881,507 @@ type RetryTest struct { PreconditionProvided bool `protobuf:"varint,5,opt,name=preconditionProvided,proto3" json:"preconditionProvided,omitempty"` // Whether we expect the method calls to eventually succeed after the client // library retries. - ExpectSuccess bool `protobuf:"varint,6,opt,name=expectSuccess,proto3" json:"expectSuccess,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + ExpectSuccess bool `protobuf:"varint,6,opt,name=expectSuccess,proto3" json:"expectSuccess,omitempty"` } -func (m *RetryTest) Reset() { *m = RetryTest{} } -func (m *RetryTest) String() string { return proto.CompactTextString(m) } -func (*RetryTest) ProtoMessage() {} -func (*RetryTest) Descriptor() ([]byte, []int) { - return fileDescriptor_c161fcfdc0c3ff1e, []int{9} +func (x *RetryTest) Reset() { + *x = RetryTest{} + if protoimpl.UnsafeEnabled { + mi := &file_test_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *RetryTest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_RetryTest.Unmarshal(m, b) -} -func (m *RetryTest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_RetryTest.Marshal(b, m, deterministic) -} -func (m *RetryTest) XXX_Merge(src proto.Message) { - xxx_messageInfo_RetryTest.Merge(m, src) -} -func (m *RetryTest) XXX_Size() int { - return xxx_messageInfo_RetryTest.Size(m) +func (x *RetryTest) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *RetryTest) XXX_DiscardUnknown() { - xxx_messageInfo_RetryTest.DiscardUnknown(m) + +func (*RetryTest) ProtoMessage() {} + +func (x *RetryTest) ProtoReflect() protoreflect.Message { + mi := &file_test_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_RetryTest proto.InternalMessageInfo +// Deprecated: Use RetryTest.ProtoReflect.Descriptor instead. +func (*RetryTest) Descriptor() ([]byte, []int) { + return file_test_proto_rawDescGZIP(), []int{10} +} -func (m *RetryTest) GetId() int32 { - if m != nil { - return m.Id +func (x *RetryTest) GetId() int32 { + if x != nil { + return x.Id } return 0 } -func (m *RetryTest) GetDescription() string { - if m != nil { - return m.Description +func (x *RetryTest) GetDescription() string { + if x != nil { + return x.Description } return "" } -func (m *RetryTest) GetCases() []*InstructionList { - if m != nil { - return m.Cases +func (x *RetryTest) GetCases() []*InstructionList { + if x != nil { + return x.Cases } return nil } -func (m *RetryTest) GetMethods() []*Method { - if m != nil { - return m.Methods +func (x *RetryTest) GetMethods() []*Method { + if x != nil { + return x.Methods } return nil } -func (m *RetryTest) GetPreconditionProvided() bool { - if m != nil { - return m.PreconditionProvided +func (x *RetryTest) GetPreconditionProvided() bool { + if x != nil { + return x.PreconditionProvided } return false } -func (m *RetryTest) GetExpectSuccess() bool { - if m != nil { - return m.ExpectSuccess +func (x *RetryTest) GetExpectSuccess() bool { + if x != nil { + return x.ExpectSuccess } return false } -func init() { - proto.RegisterEnum("google.cloud.conformance.storage.v1.UrlStyle", UrlStyle_name, UrlStyle_value) - proto.RegisterEnum("google.cloud.conformance.storage.v1.Resource", Resource_name, Resource_value) - proto.RegisterType((*TestFile)(nil), "google.cloud.conformance.storage.v1.TestFile") - proto.RegisterType((*SigningV4Test)(nil), "google.cloud.conformance.storage.v1.SigningV4Test") - proto.RegisterMapType((map[string]string)(nil), "google.cloud.conformance.storage.v1.SigningV4Test.HeadersEntry") - proto.RegisterMapType((map[string]string)(nil), "google.cloud.conformance.storage.v1.SigningV4Test.QueryParametersEntry") - proto.RegisterType((*ConditionalMatches)(nil), "google.cloud.conformance.storage.v1.ConditionalMatches") - proto.RegisterType((*PolicyConditions)(nil), "google.cloud.conformance.storage.v1.PolicyConditions") - proto.RegisterType((*PolicyInput)(nil), "google.cloud.conformance.storage.v1.PolicyInput") - proto.RegisterMapType((map[string]string)(nil), "google.cloud.conformance.storage.v1.PolicyInput.FieldsEntry") - proto.RegisterType((*PolicyOutput)(nil), "google.cloud.conformance.storage.v1.PolicyOutput") - proto.RegisterMapType((map[string]string)(nil), "google.cloud.conformance.storage.v1.PolicyOutput.FieldsEntry") - proto.RegisterType((*PostPolicyV4Test)(nil), "google.cloud.conformance.storage.v1.PostPolicyV4Test") - proto.RegisterType((*InstructionList)(nil), "google.cloud.conformance.storage.v1.InstructionList") - proto.RegisterType((*Method)(nil), "google.cloud.conformance.storage.v1.Method") - proto.RegisterType((*RetryTest)(nil), "google.cloud.conformance.storage.v1.RetryTest") -} - -func init() { proto.RegisterFile("test.proto", fileDescriptor_c161fcfdc0c3ff1e) } - -var fileDescriptor_c161fcfdc0c3ff1e = []byte{ - // 1116 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xdd, 0x6e, 0xdb, 0x36, - 0x14, 0xae, 0xec, 0xd8, 0xb5, 0x8f, 0xdd, 0x54, 0xe3, 0xd2, 0x41, 0xf3, 0xc5, 0x66, 0x78, 0x03, - 0x96, 0x75, 0x98, 0xda, 0x7a, 0x29, 0xd0, 0x15, 0x1b, 0x86, 0xd8, 0x71, 0x1a, 0x37, 0x3f, 0xf6, - 0x68, 0x39, 0x45, 0x80, 0x01, 0x86, 0x22, 0x31, 0xb6, 0x56, 0x59, 0x54, 0x48, 0x2a, 0xa8, 0xdf, - 0x63, 0x2f, 0xb0, 0xdb, 0xbe, 0xd4, 0xae, 0x06, 0xec, 0x31, 0x06, 0x91, 0x92, 0x2d, 0xa7, 0x0e, - 0x60, 0xef, 0xe7, 0x4e, 0x3c, 0x87, 0xdf, 0xf7, 0x89, 0x87, 0x1f, 0x0f, 0x09, 0x20, 0x08, 0x17, - 0x66, 0xc8, 0xa8, 0xa0, 0xe8, 0x8b, 0x31, 0xa5, 0x63, 0x9f, 0x98, 0x8e, 0x4f, 0x23, 0xd7, 0x74, - 0x68, 0x70, 0x45, 0xd9, 0xd4, 0x0e, 0x1c, 0x62, 0x72, 0x41, 0x99, 0x3d, 0x26, 0xe6, 0xcd, 0xb3, - 0xda, 0xe7, 0x6a, 0xd2, 0x13, 0x09, 0xb9, 0x8c, 0xae, 0x9e, 0x08, 0x6f, 0x4a, 0xb8, 0xb0, 0xa7, - 0xa1, 0x62, 0x69, 0xfc, 0x9e, 0x83, 0x92, 0x45, 0xb8, 0x38, 0xf4, 0x7c, 0x82, 0x7e, 0x01, 0x9d, - 0x7b, 0xe3, 0xc0, 0x0b, 0xc6, 0xa3, 0x9b, 0xbd, 0x51, 0xac, 0xc5, 0x0d, 0xad, 0x9e, 0xdf, 0xad, - 0x34, 0x9b, 0xe6, 0x1a, 0x6a, 0xe6, 0x40, 0x81, 0xcf, 0xf7, 0x62, 0x46, 0xbc, 0xcd, 0xb3, 0x43, - 0x8e, 0xae, 0x60, 0x27, 0xa4, 0x5c, 0x8c, 0x42, 0xea, 0x7b, 0xce, 0x6c, 0xa1, 0x90, 0x93, 0x0a, - 0xcf, 0xd7, 0x52, 0xe8, 0x53, 0x2e, 0xfa, 0x12, 0x9f, 0x88, 0x7c, 0x14, 0xde, 0x8a, 0x70, 0xd4, - 0x83, 0x0a, 0x23, 0x82, 0xcd, 0x12, 0xfa, 0xbc, 0xa4, 0x37, 0xd7, 0xa2, 0xc7, 0x31, 0x4e, 0xf2, - 0x02, 0x4b, 0x3f, 0x79, 0xe3, 0xcf, 0x22, 0x3c, 0x58, 0x5a, 0x1a, 0xaa, 0x41, 0xe9, 0xca, 0xf3, - 0xc9, 0x99, 0x3d, 0x25, 0x86, 0x56, 0xd7, 0x76, 0xcb, 0x78, 0x3e, 0x46, 0x75, 0xa8, 0xb8, 0x84, - 0x3b, 0xcc, 0x0b, 0x85, 0x47, 0x03, 0x23, 0x27, 0xd3, 0xd9, 0x10, 0xfa, 0x04, 0x8a, 0x97, 0x91, - 0xf3, 0x96, 0x08, 0x23, 0x2f, 0x93, 0xc9, 0x28, 0x8e, 0xd3, 0xcb, 0x5f, 0x89, 0x23, 0x8c, 0x2d, - 0x15, 0x57, 0xa3, 0x38, 0x3e, 0x25, 0x62, 0x42, 0x5d, 0xa3, 0xa0, 0xe2, 0x6a, 0x84, 0x3e, 0x03, - 0x20, 0xef, 0x42, 0x8f, 0xd9, 0x52, 0xa8, 0x58, 0xd7, 0x76, 0xf3, 0x38, 0x13, 0x41, 0x2f, 0xa0, - 0x3c, 0xdf, 0x6e, 0xe3, 0x7e, 0x5d, 0xdb, 0xad, 0x34, 0x6b, 0x69, 0x19, 0x52, 0x43, 0x98, 0x56, - 0x3a, 0x03, 0x2f, 0x26, 0xc7, 0x6b, 0x20, 0xef, 0x42, 0xe2, 0x08, 0xe2, 0x0e, 0x99, 0x6f, 0x94, - 0xd4, 0x1a, 0x32, 0x21, 0x74, 0x01, 0xf7, 0x27, 0xc4, 0x76, 0x09, 0xe3, 0x46, 0x59, 0x16, 0xf8, - 0xa7, 0xcd, 0x1d, 0x62, 0x1e, 0x29, 0x86, 0x4e, 0x20, 0xd8, 0x0c, 0xa7, 0x7c, 0x88, 0x81, 0x7e, - 0x1d, 0x11, 0x36, 0x1b, 0x85, 0x36, 0xb3, 0xa7, 0x44, 0xc4, 0x1a, 0x20, 0x35, 0x5e, 0xfd, 0x03, - 0x8d, 0x9f, 0x63, 0xaa, 0xfe, 0x9c, 0x49, 0x69, 0x3d, 0xbc, 0x5e, 0x8e, 0xc6, 0x25, 0xe6, 0xce, - 0x84, 0x4c, 0x89, 0x51, 0x51, 0x25, 0x56, 0x23, 0xd4, 0x85, 0x52, 0xc4, 0xfc, 0x81, 0x98, 0xf9, - 0xc4, 0xa8, 0xd6, 0xb5, 0xdd, 0xed, 0xe6, 0xb7, 0x6b, 0xfd, 0xc3, 0x30, 0x01, 0xe1, 0x39, 0x1c, - 0x3d, 0x85, 0x8f, 0xd5, 0x3e, 0xb7, 0x68, 0x14, 0xb8, 0x47, 0x94, 0x8b, 0x20, 0xb6, 0xcf, 0x03, - 0xa9, 0xb7, 0x2a, 0x85, 0x5e, 0x82, 0x91, 0x96, 0xbc, 0x6d, 0x07, 0x34, 0xf0, 0x1c, 0xdb, 0xc7, - 0xe4, 0x3a, 0x22, 0x5c, 0x18, 0xdb, 0x12, 0x76, 0x67, 0x1e, 0x35, 0x61, 0x27, 0xcd, 0x0d, 0x04, - 0xf3, 0x82, 0xb1, 0x45, 0xe3, 0xba, 0x18, 0x0f, 0x25, 0x6e, 0x65, 0xae, 0xf6, 0x12, 0xaa, 0xd9, - 0x1d, 0x41, 0x3a, 0xe4, 0xdf, 0x92, 0x59, 0x62, 0xf0, 0xf8, 0x13, 0xed, 0x40, 0xe1, 0xc6, 0xf6, - 0x23, 0x92, 0xb8, 0x5a, 0x0d, 0x5e, 0xe6, 0x5e, 0x68, 0xb5, 0x16, 0xec, 0xac, 0xaa, 0xf4, 0x26, - 0x1c, 0x8d, 0x3d, 0x40, 0x6d, 0x1a, 0xb8, 0x5e, 0x6c, 0x5e, 0xdb, 0x3f, 0xb5, 0x85, 0x33, 0x21, - 0x3c, 0x71, 0x39, 0x23, 0x9c, 0xc7, 0x2e, 0x8f, 0xdb, 0x51, 0x19, 0x67, 0x22, 0x8d, 0x4b, 0xd0, - 0xd5, 0xf9, 0x9f, 0x63, 0x39, 0x32, 0x01, 0x39, 0x34, 0x10, 0x24, 0x10, 0x27, 0x24, 0x18, 0x8b, - 0x09, 0xb6, 0x83, 0x31, 0x91, 0xd8, 0x02, 0x5e, 0x91, 0x89, 0x35, 0xb8, 0xb0, 0x99, 0xe0, 0x6f, - 0x3c, 0x31, 0x91, 0x0d, 0xa9, 0x8c, 0x33, 0x91, 0xc6, 0x6f, 0x5b, 0x50, 0x51, 0x22, 0xdd, 0x20, - 0x8c, 0x44, 0xc6, 0x2e, 0xda, 0x9d, 0x76, 0xc9, 0xfd, 0x2f, 0x76, 0xc9, 0xdf, 0x6d, 0x97, 0x45, - 0x5b, 0xd9, 0xba, 0xa3, 0xad, 0x14, 0x96, 0xda, 0xca, 0x87, 0xed, 0xa3, 0xf0, 0x1f, 0xb5, 0x0f, - 0x0b, 0x8a, 0x57, 0x1e, 0xf1, 0x5d, 0x6e, 0x94, 0xe4, 0xb9, 0xfd, 0x61, 0xcd, 0xde, 0x3e, 0x2f, - 0xb0, 0x79, 0x28, 0xe1, 0xea, 0xb0, 0x26, 0x5c, 0x68, 0x08, 0xe0, 0xcc, 0xb7, 0xd8, 0x28, 0xcb, - 0x1f, 0x7a, 0xbe, 0x01, 0xf3, 0xc2, 0x1f, 0x38, 0x43, 0x54, 0xfb, 0x1e, 0x2a, 0x19, 0xb5, 0x8d, - 0x0c, 0xfb, 0x97, 0x06, 0x55, 0xc5, 0xdd, 0x8b, 0x44, 0xec, 0x0b, 0x1d, 0xf2, 0x11, 0xf3, 0x53, - 0x70, 0xc4, 0x7c, 0x34, 0x9c, 0x97, 0x42, 0x5d, 0x73, 0x3f, 0x6e, 0xf0, 0xc3, 0x8a, 0x74, 0x65, - 0x2d, 0xf6, 0xe0, 0x51, 0x7a, 0x84, 0x0f, 0x88, 0x43, 0x5d, 0xe2, 0x2a, 0x48, 0xe2, 0x8f, 0xd5, - 0xc9, 0x7f, 0xb3, 0xd4, 0x3f, 0xb4, 0xf8, 0x98, 0x2d, 0x5f, 0xb5, 0xb7, 0xaf, 0x3a, 0xed, 0xc3, - 0xab, 0x0e, 0x43, 0x25, 0x5c, 0x6c, 0xab, 0xa4, 0xad, 0x34, 0x9f, 0x6e, 0x6a, 0x07, 0x9c, 0x25, - 0x41, 0x43, 0xa8, 0x86, 0x99, 0xfa, 0xc8, 0x25, 0x57, 0x9a, 0xcf, 0x36, 0x2e, 0x2c, 0x5e, 0xa2, - 0x69, 0x3c, 0x87, 0x87, 0xdd, 0x80, 0x0b, 0x16, 0x39, 0xf1, 0x9f, 0x9f, 0x78, 0x5c, 0xa0, 0x06, - 0x54, 0xbd, 0x45, 0x88, 0x27, 0xcd, 0x67, 0x29, 0xd6, 0xf0, 0xa0, 0x78, 0xaa, 0xae, 0x63, 0x04, - 0x5b, 0xc1, 0xe2, 0x41, 0x20, 0xbf, 0xd1, 0x31, 0x94, 0x19, 0xe1, 0x34, 0x62, 0x0e, 0x51, 0x0e, - 0x58, 0xb7, 0x23, 0xe0, 0x04, 0x85, 0x17, 0xf8, 0xc6, 0xfb, 0x1c, 0x94, 0xe7, 0x2f, 0x14, 0xb4, - 0x0d, 0x39, 0xcf, 0x95, 0x62, 0x05, 0x9c, 0xf3, 0xdc, 0x35, 0xde, 0x1d, 0xaf, 0xa1, 0xe0, 0xd8, - 0x9c, 0xa4, 0x4f, 0xa2, 0xbd, 0xb5, 0x7e, 0xe4, 0x56, 0x4d, 0xb0, 0xa2, 0x40, 0x1d, 0xb8, 0xaf, - 0x5e, 0x21, 0xdc, 0xd8, 0x92, 0x6c, 0xdf, 0xac, 0xc5, 0xa6, 0x4a, 0x85, 0x53, 0x6c, 0x7c, 0x4d, - 0x85, 0x8c, 0xcc, 0x4f, 0x63, 0x9f, 0xd1, 0x1b, 0xcf, 0x25, 0xea, 0xa1, 0x53, 0xc2, 0x2b, 0x73, - 0xe8, 0x4b, 0x78, 0xa0, 0xec, 0x3d, 0x88, 0x1c, 0x87, 0x70, 0x2e, 0x5b, 0x57, 0x09, 0x2f, 0x07, - 0x1f, 0xf7, 0xa0, 0x94, 0x76, 0x55, 0xb4, 0x0d, 0xd0, 0xdf, 0xb7, 0x8e, 0x46, 0x03, 0xeb, 0xe2, - 0xa4, 0xa3, 0xdf, 0x43, 0x06, 0xec, 0x9c, 0x77, 0xb1, 0x35, 0xdc, 0x3f, 0x19, 0x1d, 0xf5, 0x06, - 0x56, 0xe7, 0x20, 0xc9, 0x68, 0xe8, 0x53, 0x78, 0xd4, 0x1a, 0xb6, 0x8f, 0x3b, 0xd6, 0xa8, 0xd5, - 0x1b, 0x9e, 0x1d, 0xc8, 0xf4, 0xd9, 0xfe, 0x69, 0x47, 0xcf, 0x3d, 0x6e, 0x41, 0x29, 0xdd, 0x14, - 0x04, 0x50, 0x54, 0xd3, 0xf4, 0x7b, 0xf1, 0x77, 0xaf, 0xf5, 0xba, 0xd3, 0xb6, 0x74, 0x0d, 0xe9, - 0x50, 0x3d, 0xeb, 0x59, 0xdd, 0xc3, 0x6e, 0x7b, 0xdf, 0xea, 0xf6, 0xce, 0xf4, 0x1c, 0xaa, 0x42, - 0xe9, 0xe8, 0x74, 0xbf, 0x3d, 0x3a, 0xee, 0x5c, 0xe8, 0xf9, 0xd6, 0x1b, 0xf8, 0xca, 0xa1, 0xd3, - 0x75, 0x2a, 0xd5, 0xd7, 0xde, 0xe7, 0xbe, 0x7e, 0xa5, 0xe6, 0xb5, 0xe5, 0xbc, 0x41, 0x92, 0x3b, - 0x7f, 0x66, 0xca, 0x67, 0xa9, 0xd9, 0x5e, 0x00, 0x2f, 0x8b, 0xb2, 0x21, 0x7f, 0xf7, 0x77, 0x00, - 0x00, 0x00, 0xff, 0xff, 0x2e, 0x18, 0x4b, 0xe0, 0x21, 0x0c, 0x00, 0x00, +var File_test_proto protoreflect.FileDescriptor + +var file_test_proto_rawDesc = []byte{ + 0x0a, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x23, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x76, + 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x22, 0xa1, 0x02, 0x0a, 0x08, 0x54, 0x65, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x12, + 0x5c, 0x0a, 0x10, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x34, 0x5f, 0x74, 0x65, + 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, + 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x56, 0x34, 0x54, 0x65, 0x73, 0x74, 0x52, 0x0e, 0x73, + 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x56, 0x34, 0x54, 0x65, 0x73, 0x74, 0x73, 0x12, 0x66, 0x0a, + 0x14, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x76, 0x34, 0x5f, + 0x74, 0x65, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x56, 0x34, 0x54, 0x65, + 0x73, 0x74, 0x52, 0x11, 0x70, 0x6f, 0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x56, 0x34, + 0x54, 0x65, 0x73, 0x74, 0x73, 0x12, 0x4f, 0x0a, 0x0b, 0x72, 0x65, 0x74, 0x72, 0x79, 0x5f, 0x74, + 0x65, 0x73, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, + 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x52, 0x65, 0x74, 0x72, 0x79, 0x54, 0x65, 0x73, 0x74, 0x52, 0x0a, 0x72, 0x65, 0x74, 0x72, + 0x79, 0x54, 0x65, 0x73, 0x74, 0x73, 0x22, 0xe5, 0x06, 0x0a, 0x0d, 0x53, 0x69, 0x67, 0x6e, 0x69, + 0x6e, 0x67, 0x56, 0x34, 0x54, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, + 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x16, + 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x1e, + 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x38, + 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x78, 0x70, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x55, 0x72, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, + 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x55, 0x72, 0x6c, 0x12, 0x59, 0x0a, 0x07, 0x68, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x56, 0x34, 0x54, 0x65, 0x73, 0x74, 0x2e, + 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x68, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x72, 0x0a, 0x10, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x47, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x63, + 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, + 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x56, 0x34, 0x54, + 0x65, 0x73, 0x74, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x63, 0x68, + 0x65, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, + 0x65, 0x12, 0x49, 0x0a, 0x08, 0x75, 0x72, 0x6c, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x18, 0x0c, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, + 0x75, 0x64, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x73, + 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x72, 0x6c, 0x53, 0x74, 0x79, + 0x6c, 0x65, 0x52, 0x08, 0x75, 0x72, 0x6c, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x12, 0x30, 0x0a, 0x13, + 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x48, 0x6f, 0x73, 0x74, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x62, 0x75, 0x63, 0x6b, 0x65, + 0x74, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3a, + 0x0a, 0x18, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x69, + 0x63, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x18, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x69, + 0x63, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x14, 0x65, 0x78, + 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x6f, 0x53, 0x69, + 0x67, 0x6e, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, + 0x65, 0x64, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x6f, 0x53, 0x69, 0x67, 0x6e, 0x1a, 0x3a, + 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x42, 0x0a, 0x14, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x34, + 0x0a, 0x12, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x4d, 0x61, 0x74, + 0x63, 0x68, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x62, 0x0a, 0x10, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x43, 0x6f, + 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2e, 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x05, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x4c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x73, 0x57, 0x69, 0x74, 0x68, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x73, 0x57, 0x69, 0x74, 0x68, 0x22, 0x94, 0x04, 0x0a, 0x0b, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x65, + 0x12, 0x49, 0x0a, 0x08, 0x75, 0x72, 0x6c, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, + 0x64, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x73, 0x74, + 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x72, 0x6c, 0x53, 0x74, 0x79, 0x6c, + 0x65, 0x52, 0x08, 0x75, 0x72, 0x6c, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x12, 0x30, 0x0a, 0x13, 0x62, + 0x75, 0x63, 0x6b, 0x65, 0x74, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, + 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, + 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, + 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1e, 0x0a, + 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, + 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x54, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, + 0x63, 0x65, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x55, 0x0a, + 0x0a, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x35, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, + 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x73, 0x74, 0x6f, + 0x72, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x43, 0x6f, + 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, + 0xe8, 0x01, 0x0a, 0x0c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, + 0x72, 0x6c, 0x12, 0x55, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, + 0x64, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x73, 0x74, + 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x34, 0x0a, 0x15, 0x65, 0x78, 0x70, + 0x65, 0x63, 0x74, 0x65, 0x64, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x50, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, + 0x65, 0x64, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x1a, + 0x39, 0x0a, 0x0b, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xdf, 0x01, 0x0a, 0x10, 0x50, + 0x6f, 0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x56, 0x34, 0x54, 0x65, 0x73, 0x74, 0x12, + 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x52, 0x0a, 0x0b, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x49, 0x6e, 0x70, 0x75, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, + 0x65, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x52, 0x0b, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x49, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x55, 0x0a, 0x0c, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x52, 0x0c, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0x5c, 0x0a, 0x0a, + 0x52, 0x65, 0x74, 0x72, 0x79, 0x54, 0x65, 0x73, 0x74, 0x73, 0x12, 0x4e, 0x0a, 0x0a, 0x72, 0x65, + 0x74, 0x72, 0x79, 0x54, 0x65, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x63, 0x6f, + 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x74, 0x72, 0x79, 0x54, 0x65, 0x73, 0x74, 0x52, 0x0a, + 0x72, 0x65, 0x74, 0x72, 0x79, 0x54, 0x65, 0x73, 0x74, 0x73, 0x22, 0x35, 0x0a, 0x0f, 0x49, 0x6e, + 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x22, 0x0a, + 0x0c, 0x69, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0c, 0x69, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x22, 0x69, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x4b, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, + 0x64, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x73, 0x74, + 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0xaa, 0x02, 0x0a, + 0x09, 0x52, 0x65, 0x74, 0x72, 0x79, 0x54, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x4a, 0x0a, 0x05, + 0x63, 0x61, 0x73, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, + 0x74, 0x52, 0x05, 0x63, 0x61, 0x73, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x68, + 0x6f, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, + 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x12, + 0x32, 0x0a, 0x14, 0x70, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x50, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x70, + 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x76, 0x69, + 0x64, 0x65, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x53, 0x75, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x65, 0x78, 0x70, 0x65, + 0x63, 0x74, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2a, 0x4f, 0x0a, 0x08, 0x55, 0x72, 0x6c, + 0x53, 0x74, 0x79, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x41, 0x54, 0x48, 0x5f, 0x53, 0x54, + 0x59, 0x4c, 0x45, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x56, 0x49, 0x52, 0x54, 0x55, 0x41, 0x4c, + 0x5f, 0x48, 0x4f, 0x53, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x54, 0x59, 0x4c, 0x45, 0x10, 0x01, 0x12, + 0x19, 0x0a, 0x15, 0x42, 0x55, 0x43, 0x4b, 0x45, 0x54, 0x5f, 0x42, 0x4f, 0x55, 0x4e, 0x44, 0x5f, + 0x48, 0x4f, 0x53, 0x54, 0x4e, 0x41, 0x4d, 0x45, 0x10, 0x02, 0x2a, 0x42, 0x0a, 0x08, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x42, 0x55, 0x43, 0x4b, 0x45, 0x54, + 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x4f, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x10, 0x01, 0x12, 0x10, + 0x0a, 0x0c, 0x4e, 0x4f, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x02, + 0x12, 0x0c, 0x0a, 0x08, 0x48, 0x4d, 0x41, 0x43, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x03, 0x42, 0x7c, + 0x0a, 0x27, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, + 0x75, 0x64, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x73, + 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x50, 0x01, 0x5a, 0x23, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, + 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2f, 0x76, 0x31, + 0xaa, 0x02, 0x29, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, + 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x56, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x73, + 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_test_proto_rawDescOnce sync.Once + file_test_proto_rawDescData = file_test_proto_rawDesc +) + +func file_test_proto_rawDescGZIP() []byte { + file_test_proto_rawDescOnce.Do(func() { + file_test_proto_rawDescData = protoimpl.X.CompressGZIP(file_test_proto_rawDescData) + }) + return file_test_proto_rawDescData +} + +var file_test_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_test_proto_msgTypes = make([]protoimpl.MessageInfo, 15) +var file_test_proto_goTypes = []interface{}{ + (UrlStyle)(0), // 0: google.cloud.conformance.storage.v1.UrlStyle + (Resource)(0), // 1: google.cloud.conformance.storage.v1.Resource + (*TestFile)(nil), // 2: google.cloud.conformance.storage.v1.TestFile + (*SigningV4Test)(nil), // 3: google.cloud.conformance.storage.v1.SigningV4Test + (*ConditionalMatches)(nil), // 4: google.cloud.conformance.storage.v1.ConditionalMatches + (*PolicyConditions)(nil), // 5: google.cloud.conformance.storage.v1.PolicyConditions + (*PolicyInput)(nil), // 6: google.cloud.conformance.storage.v1.PolicyInput + (*PolicyOutput)(nil), // 7: google.cloud.conformance.storage.v1.PolicyOutput + (*PostPolicyV4Test)(nil), // 8: google.cloud.conformance.storage.v1.PostPolicyV4Test + (*RetryTests)(nil), // 9: google.cloud.conformance.storage.v1.RetryTests + (*InstructionList)(nil), // 10: google.cloud.conformance.storage.v1.InstructionList + (*Method)(nil), // 11: google.cloud.conformance.storage.v1.Method + (*RetryTest)(nil), // 12: google.cloud.conformance.storage.v1.RetryTest + nil, // 13: google.cloud.conformance.storage.v1.SigningV4Test.HeadersEntry + nil, // 14: google.cloud.conformance.storage.v1.SigningV4Test.QueryParametersEntry + nil, // 15: google.cloud.conformance.storage.v1.PolicyInput.FieldsEntry + nil, // 16: google.cloud.conformance.storage.v1.PolicyOutput.FieldsEntry + (*timestamppb.Timestamp)(nil), // 17: google.protobuf.Timestamp +} +var file_test_proto_depIdxs = []int32{ + 3, // 0: google.cloud.conformance.storage.v1.TestFile.signing_v4_tests:type_name -> google.cloud.conformance.storage.v1.SigningV4Test + 8, // 1: google.cloud.conformance.storage.v1.TestFile.post_policy_v4_tests:type_name -> google.cloud.conformance.storage.v1.PostPolicyV4Test + 12, // 2: google.cloud.conformance.storage.v1.TestFile.retry_tests:type_name -> google.cloud.conformance.storage.v1.RetryTest + 17, // 3: google.cloud.conformance.storage.v1.SigningV4Test.timestamp:type_name -> google.protobuf.Timestamp + 13, // 4: google.cloud.conformance.storage.v1.SigningV4Test.headers:type_name -> google.cloud.conformance.storage.v1.SigningV4Test.HeadersEntry + 14, // 5: google.cloud.conformance.storage.v1.SigningV4Test.query_parameters:type_name -> google.cloud.conformance.storage.v1.SigningV4Test.QueryParametersEntry + 0, // 6: google.cloud.conformance.storage.v1.SigningV4Test.urlStyle:type_name -> google.cloud.conformance.storage.v1.UrlStyle + 0, // 7: google.cloud.conformance.storage.v1.PolicyInput.urlStyle:type_name -> google.cloud.conformance.storage.v1.UrlStyle + 17, // 8: google.cloud.conformance.storage.v1.PolicyInput.timestamp:type_name -> google.protobuf.Timestamp + 15, // 9: google.cloud.conformance.storage.v1.PolicyInput.fields:type_name -> google.cloud.conformance.storage.v1.PolicyInput.FieldsEntry + 5, // 10: google.cloud.conformance.storage.v1.PolicyInput.conditions:type_name -> google.cloud.conformance.storage.v1.PolicyConditions + 16, // 11: google.cloud.conformance.storage.v1.PolicyOutput.fields:type_name -> google.cloud.conformance.storage.v1.PolicyOutput.FieldsEntry + 6, // 12: google.cloud.conformance.storage.v1.PostPolicyV4Test.policyInput:type_name -> google.cloud.conformance.storage.v1.PolicyInput + 7, // 13: google.cloud.conformance.storage.v1.PostPolicyV4Test.policyOutput:type_name -> google.cloud.conformance.storage.v1.PolicyOutput + 12, // 14: google.cloud.conformance.storage.v1.RetryTests.retryTests:type_name -> google.cloud.conformance.storage.v1.RetryTest + 1, // 15: google.cloud.conformance.storage.v1.Method.resources:type_name -> google.cloud.conformance.storage.v1.Resource + 10, // 16: google.cloud.conformance.storage.v1.RetryTest.cases:type_name -> google.cloud.conformance.storage.v1.InstructionList + 11, // 17: google.cloud.conformance.storage.v1.RetryTest.methods:type_name -> google.cloud.conformance.storage.v1.Method + 18, // [18:18] is the sub-list for method output_type + 18, // [18:18] is the sub-list for method input_type + 18, // [18:18] is the sub-list for extension type_name + 18, // [18:18] is the sub-list for extension extendee + 0, // [0:18] is the sub-list for field type_name +} + +func init() { file_test_proto_init() } +func file_test_proto_init() { + if File_test_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_test_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TestFile); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_test_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SigningV4Test); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_test_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ConditionalMatches); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_test_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PolicyConditions); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_test_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PolicyInput); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_test_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PolicyOutput); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_test_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PostPolicyV4Test); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_test_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RetryTests); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_test_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InstructionList); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_test_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Method); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_test_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RetryTest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_test_proto_rawDesc, + NumEnums: 2, + NumMessages: 15, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_test_proto_goTypes, + DependencyIndexes: file_test_proto_depIdxs, + EnumInfos: file_test_proto_enumTypes, + MessageInfos: file_test_proto_msgTypes, + }.Build() + File_test_proto = out.File + file_test_proto_rawDesc = nil + file_test_proto_goTypes = nil + file_test_proto_depIdxs = nil } diff --git a/storage/internal/test/conformance/test.proto b/storage/internal/test/conformance/test.proto index 2912070f883..b7f440c7cbf 100644 --- a/storage/internal/test/conformance/test.proto +++ b/storage/internal/test/conformance/test.proto @@ -21,6 +21,7 @@ import "google/protobuf/timestamp.proto"; option csharp_namespace = "Google.Cloud.Storage.V1.Tests.Conformance"; option java_package = "com.google.cloud.conformance.storage.v1"; option java_multiple_files = true; +option go_package = "google/cloud/conformance/storage/v1"; message TestFile { repeated SigningV4Test signing_v4_tests = 1; @@ -61,7 +62,11 @@ message PolicyConditions { repeated string startsWith = 2; } +// Specification documentation is located at: +// https://cloud.google.com/storage/docs/authentication/signatures + message PolicyInput { + // http or https string scheme = 1; UrlStyle urlStyle = 2; string bucketBoundHostname = 3; @@ -69,6 +74,15 @@ message PolicyInput { string object = 5; int32 expiration = 6; google.protobuf.Timestamp timestamp = 7; + /* + fields with strict equivalence which are added into + PolicyOutput.expectedDecodedPolicy to generate the + signature. + Expectations + E.1: Order them in lexigraphical order so it's the + signature can be verified across different language + implementations. + */ map fields = 8; PolicyConditions conditions = 9; } @@ -76,6 +90,54 @@ message PolicyInput { message PolicyOutput { string url = 1; map fields = 2; + /* + Expectations + E.1: PolicyInput.fields must be prepended to form expectedDecodedPolicy + for consistent result across languages. Ordering doesn't matter to the + service but the decision is made to make it easier to conform implementations + in implementation. + Example: + # Step 1 + PolicyInput.fields has: + { + "content-disposition":"attachment; filename=\"~._-%=/é0Aa\"", + "content-encoding":"gzip", + "content-type":"text/plain", + "success_action_redirect":"http://www.google.com/" + } + # Step 2 + The expectedDecodedPolicy before prepending the PolicyInput.fields + would look like this: + { + "conditions":[ + ...prepend here in the same order provided in PolicyInput.fields... + {"bucket":"bucket-name"}, + {"key":"test-object"}, + {"x-goog-date":"20200123T043530Z"}, + {"x-goog-credential":"test-iam-credentials@dummy-project-id.iam.gserviceaccount.com/20200123/auto/storage/goog4_request"}, + {"x-goog-algorithm":"GOOG4-RSA-SHA256"} + ], + "expiration":"2020-01-23T04:35:40Z" + } + # Step 3 + Then expectedDecodedPolicy should prepends PolicyInput.fields in + the same order to PolicyOutput.expectedDecodedPolicy `conditions` key. + { + "conditions":[ + {"content-disposition":"attachment; filename=\"~._-%=/é0Aa\""}, + {"content-encoding":"gzip"}, + {"content-type":"text/plain"}, + {"success_action_redirect":"http://www.google.com/"}, + {"bucket":"bucket-name"}, + {"key":"test-object"}, + {"x-goog-date":"20200123T043530Z"}, + {"x-goog-credential":"test-iam-credentials@dummy-project-id.iam.gserviceaccount.com/20200123/auto/storage/goog4_request"}, + {"x-goog-algorithm":"GOOG4-RSA-SHA256"} + ], + "expiration":"2020-01-23T04:35:40Z" + } + */ + string expectedDecodedPolicy = 3; } @@ -86,14 +148,20 @@ message PostPolicyV4Test { } /* -Data types for retry conformance tests. + ------------------------------------------------------------------------------ + Data types for retry conformance tests + ------------------------------------------------------------------------------ */ +message RetryTests { + repeated RetryTest retryTests = 1; +} + // A list of instructions to send as headers to the GCS emulator. Each // instruction will force a specified failure for that request. message InstructionList { repeated string instructions = 1; -} +} // Test resources that are necessary for a method call. For example, // storage.objects.get would require BUCKET and OBJECT. @@ -114,12 +182,13 @@ message Method { // Schema for a retry test, corresponding to a single scenario from the design // doc. message RetryTest { + // Scenario number int32 id = 1; // Human-readable description of the test case. string description = 2; - // List of emulator instructions. + // list of emulator instruction sets. repeated InstructionList cases = 3; // List of API methods to be tested. From 31ebabd41a647996d86fe59378c207bde22bc7ce Mon Sep 17 00:00:00 2001 From: Brenna Epp Date: Tue, 31 Aug 2021 17:55:29 -0500 Subject: [PATCH 17/25] fix --- storage/conformance_test.go | 190 ++++++++++++++++++++---------------- 1 file changed, 106 insertions(+), 84 deletions(-) diff --git a/storage/conformance_test.go b/storage/conformance_test.go index afb137e7440..bdc3da79e02 100644 --- a/storage/conformance_test.go +++ b/storage/conformance_test.go @@ -20,9 +20,9 @@ import ( "encoding/base64" "encoding/json" "fmt" - "io" "io/ioutil" "net/http" + "net/http/httputil" "net/url" "os" "strconv" @@ -112,41 +112,12 @@ type retryFunc func(ctx context.Context, c *Client, fs *resources, preconditions // because multiple library methods may use the same call (e.g. get could be a // read or just a metadata get). var methods = map[string][]retryFunc{ - "storage.objects.get": { + "storage.buckets.get": { func(ctx context.Context, c *Client, fs *resources, _ bool) error { - _, err := c.Bucket(fs.bucket.Name).Object(fs.object.Name).Attrs(ctx) - return err - }, - func(ctx context.Context, c *Client, fs *resources, _ bool) error { - r, err := c.Bucket(fs.bucket.Name).Object(fs.object.Name).NewReader(ctx) - if err != nil { - return err - } - _, err = io.Copy(ioutil.Discard, r) + _, err := c.Bucket(fs.bucket.Name).Attrs(ctx) return err }, }, - "storage.objects.update": { - func(ctx context.Context, c *Client, fs *resources, preconditions bool) error { - uattrs := ObjectAttrsToUpdate{Metadata: map[string]string{"foo": "bar"}} - obj := c.Bucket(fs.bucket.Name).Object(fs.object.Name) - if preconditions { - obj = obj.If(Conditions{MetagenerationMatch: fs.object.Metageneration}) - } - _, err := obj.Update(ctx, uattrs) - return err - }, - }, - "storage.buckets.update": { - func(ctx context.Context, c *Client, fs *resources, preconditions bool) error { - uattrs := BucketAttrsToUpdate{StorageClass: "ARCHIVE"} - bkt := c.Bucket(fs.bucket.Name) - if preconditions { - bkt = bkt.If(BucketConditions{MetagenerationMatch: fs.bucket.MetaGeneration}) - } - _, err := bkt.Update(ctx, uattrs) - return err - }}, } func TestRetryConformance(t *testing.T) { @@ -154,67 +125,64 @@ func TestRetryConformance(t *testing.T) { if host == "" { t.Skip("This test must use the testbench emulator; set STORAGE_EMULATOR_HOST to run.") } - host = "http://" + host ctx := context.Background() // Create non-wrapped client to use for setup steps. - client, err := NewClient(ctx, option.WithEndpoint(host+"/storage/v1/")) + client, err := NewClient(ctx) if err != nil { t.Fatalf("storage.NewClient: %v", err) } _, _, testFiles := parseFiles(t) + for _, testFile := range testFiles { - for _, tc := range testFile.RetryTests { - for _, instructions := range tc.Cases { - for _, m := range tc.Methods { - if len(methods[m.Name]) == 0 { - t.Logf("No tests for operation %v", m.Name) + for _, retryTest := range testFile.RetryTests { + for _, instructions := range retryTest.Cases { + for _, method := range retryTest.Methods { + if len(methods[method.Name]) == 0 { + t.Logf("No tests for operation %v", method.Name) } - for i, f := range methods[m.Name] { - testName := fmt.Sprintf("%v-%v-%v-%v", tc.Id, instructions.Instructions, m.Name, i) + for i, fn := range methods[method.Name] { + testName := fmt.Sprintf("%v-%v-%v-%v", retryTest.Id, instructions.Instructions, method.Name, i) t.Run(testName, func(t *testing.T) { - // Create the retry test in the emulator to handle instructions. - testID, err := createRetryTest(host, map[string][]string{ - m.Name: instructions.Instructions, + // Create the retry subtest + subtest := &retrySubtest{T: t, name: testName} + err := subtest.create(host, map[string][]string{ + method.Name: instructions.Instructions, }) if err != nil { t.Fatalf("setting up retry test: %v", err) } + // Create necessary test resources in the emulator fs := &resources{} - for _, f := range m.Resources { - if err := fs.populate(ctx, client, f); err != nil { + for _, resource := range method.Resources { + if err := fs.populate(ctx, client, resource); err != nil { t.Fatalf("creating test resources: %v", err) } } - // Create wrapped client which will send emulator instructions. - wrapped, err := wrappedClient(host, testID) - if err != nil { - t.Errorf("error creating wrapped client: %v", err) - } - err = f(ctx, wrapped, fs, tc.PreconditionProvided) - if tc.ExpectSuccess && err != nil { + // Test + err = fn(ctx, subtest.wrappedClient, fs, retryTest.PreconditionProvided) + if retryTest.ExpectSuccess && err != nil { t.Errorf("want success, got %v", err) } - if !tc.ExpectSuccess && err == nil { + if !retryTest.ExpectSuccess && err == nil { t.Errorf("want failure, got success") } // Verify that all instructions were used up during the test // (indicates that the client sent the correct requests). - if err := checkRetryTest(host, testID); err != nil { + if err := subtest.check(); err != nil { t.Errorf("checking instructions: %v", err) } // Close out test in emulator. - if err := deleteRetryTest(host, testID); err != nil { + if err := subtest.delete(); err != nil { t.Errorf("deleting retry test: %v", err) } - }) } @@ -225,44 +193,79 @@ func TestRetryConformance(t *testing.T) { } -// Create a retry test resource in the emulator. Returns the ID to pass as -// a header in the test execution. -func createRetryTest(host string, instructions map[string][]string) (string, error) { - endpoint := host + "/retry_test" +type retrySubtest struct { + *testing.T + name string + id string // ID to pass as a header in the test execution + host *url.URL // set the path when using; path is not guaranteed betwen calls + wrappedClient *Client +} + +// Create a retry test resource in the emulator +func (rt *retrySubtest) create(host string, instructions map[string][]string) error { + endpoint, err := parseURL(host) + if err != nil { + return err + } + rt.host = endpoint + c := http.DefaultClient data := struct { - Instructions map[string][]string `json:"test_instructions"` + Instructions map[string][]string `json:"instructions"` }{ Instructions: instructions, } buf := new(bytes.Buffer) if err := json.NewEncoder(buf).Encode(data); err != nil { - return "", fmt.Errorf("encoding request: %v", err) + return fmt.Errorf("encoding request: %v", err) } - resp, err := c.Post(endpoint, "application/json", buf) + + rt.host.Path = "retry_test" + resp, err := c.Post(rt.host.String(), "application/json", buf) if err != nil || resp.StatusCode != 200 { - return "", fmt.Errorf("creating retry test: err: %v, resp: %+v", err, resp) + return fmt.Errorf("creating retry test: err: %v, resp: %+v", err, resp) } - defer resp.Body.Close() + defer func() { + closeErr := resp.Body.Close() + if err == nil { + err = closeErr + } + }() testRes := struct { TestID string `json:"id"` }{} if err := json.NewDecoder(resp.Body).Decode(&testRes); err != nil { - return "", fmt.Errorf("decoding test ID: %v", err) + return fmt.Errorf("decoding test ID: %v", err) + } + + rt.id = testRes.TestID + + // Create wrapped client which will send emulator instructions + rt.host.Path = "" + client, err := wrappedClient(rt.T, rt.host.String(), rt.id) + if err != nil { + return fmt.Errorf("creating wrapped client: %v", err) } - return testRes.TestID, nil + rt.wrappedClient = client + + return nil } // Verify that all instructions for a given retry testID have been used up. -func checkRetryTest(host, testID string) error { - endpoint := strings.Join([]string{host, "retry_test", testID}, "/") +func (rt *retrySubtest) check() error { + rt.host.Path = strings.Join([]string{"retry_test", rt.id}, "/") c := http.DefaultClient - resp, err := c.Get(endpoint) + resp, err := c.Get(rt.host.String()) if err != nil || resp.StatusCode != 200 { return fmt.Errorf("getting retry test: err: %v, resp: %+v", err, resp) } - defer resp.Body.Close() + defer func() { + closeErr := resp.Body.Close() + if err == nil { + err = closeErr + } + }() testRes := struct { Instructions map[string][]string Completed bool @@ -277,10 +280,10 @@ func checkRetryTest(host, testID string) error { } // Delete a retry test resource. -func deleteRetryTest(host, testID string) error { - endpoint := strings.Join([]string{host, "retry_test", testID}, "/") +func (rt *retrySubtest) delete() error { + rt.host.Path = strings.Join([]string{"retry_test", rt.id}, "/") c := http.DefaultClient - req, err := http.NewRequest("DELETE", endpoint, nil) + req, err := http.NewRequest("DELETE", rt.host.String(), nil) if err != nil { return fmt.Errorf("creating request: %v", err) } @@ -291,22 +294,29 @@ func deleteRetryTest(host, testID string) error { return nil } -type withTestID struct { +type testRoundTripper struct { + *testing.T rt http.RoundTripper testID string } -func (wt *withTestID) RoundTrip(r *http.Request) (*http.Response, error) { - r.Header.Add("x-retry-test-id", wt.testID) +func (wt *testRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) { + r.Header.Set("x-retry-test-id", wt.testID) + + requestDump, err := httputil.DumpRequest(r, false) + if err != nil { + wt.Logf("error creating request dump: %v", err) + } + resp, err := wt.rt.RoundTrip(r) - //if err != nil{ - // log.Printf("Error: %+v", err) - //} + if err != nil { + wt.Logf("roundtrip error (may be expected): %v\nrequest: %s", err, requestDump) + } return resp, err } // Create custom client that sends instruction -func wrappedClient(host, testID string) (*Client, error) { +func wrappedClient(t *testing.T, host, testID string) (*Client, error) { ctx := context.Background() base := http.DefaultTransport trans, err := htransport.NewTransport(ctx, base, option.WithScopes(raw.DevstorageFullControlScope), @@ -316,8 +326,8 @@ func wrappedClient(host, testID string) (*Client, error) { } c := http.Client{Transport: trans} - // Add RoundTripper to the created HTTP client. - wrappedTrans := &withTestID{rt: c.Transport, testID: testID} + // Add RoundTripper to the created HTTP client + wrappedTrans := &testRoundTripper{rt: c.Transport, testID: testID, T: t} c.Transport = wrappedTrans // Supply this client to storage.NewClient @@ -325,6 +335,18 @@ func wrappedClient(host, testID string) (*Client, error) { return client, err } +// A url is only parsed correctly by the url package if it has a scheme, +// so we have to check and build it ourselves if not supplied in host +// Assumes http if not provided +func parseURL(host string) (*url.URL, error) { + if strings.Contains(host, "://") { + return url.Parse(host) + } else { + url := &url.URL{Scheme: "http", Host: host} + return url, nil + } +} + func TestPostPolicyV4Conformance(t *testing.T) { oldUTCNow := utcNow defer func() { From 1974fa8bd1b25c2e228f531bdcd728aae9d112fa Mon Sep 17 00:00:00 2001 From: Brenna Epp Date: Wed, 29 Sep 2021 16:04:13 -0500 Subject: [PATCH 18/25] add some comments --- storage/conformance_test.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/storage/conformance_test.go b/storage/conformance_test.go index bdc3da79e02..af4ed8c7e12 100644 --- a/storage/conformance_test.go +++ b/storage/conformance_test.go @@ -40,11 +40,13 @@ import ( ) var ( + // Resource vars for retry tests bucketIDs = uid.NewSpace("bucket", nil) objectIDs = uid.NewSpace("object", nil) notificationIDs = uid.NewSpace("notification", nil) projectID = "my-project-id" serviceAccountEmail = "my-sevice-account@my-project-id.iam.gserviceaccount.com" + randomBytesToWrite = []byte("abcdef") ) // Holds the resources for a particular test case. Only the necessary fields will @@ -72,7 +74,7 @@ func (fs *resources) populate(ctx context.Context, c *Client, resource storage_v // Assumes bucket has been populated first. obj := c.Bucket(fs.bucket.Name).Object(objectIDs.New()) w := obj.NewWriter(ctx) - if _, err := w.Write([]byte("abcdef")); err != nil { + if _, err := w.Write(randomBytesToWrite); err != nil { return fmt.Errorf("writing object: %v", err) } if err := w.Close(); err != nil { @@ -123,6 +125,8 @@ var methods = map[string][]retryFunc{ func TestRetryConformance(t *testing.T) { host := os.Getenv("STORAGE_EMULATOR_HOST") if host == "" { + // This test is currently skipped in CI as the env variable is not set + // TODO: Add test to CI t.Skip("This test must use the testbench emulator; set STORAGE_EMULATOR_HOST to run.") } From d6c80fbcfab358ac799732f43c5a0403a1962413 Mon Sep 17 00:00:00 2001 From: Brenna Epp Date: Wed, 29 Sep 2021 16:26:53 -0500 Subject: [PATCH 19/25] call error from function --- storage/conformance_test.go | 45 ++++++++++++++----------------------- 1 file changed, 17 insertions(+), 28 deletions(-) diff --git a/storage/conformance_test.go b/storage/conformance_test.go index af4ed8c7e12..f8fee301a37 100644 --- a/storage/conformance_test.go +++ b/storage/conformance_test.go @@ -153,12 +153,9 @@ func TestRetryConformance(t *testing.T) { // Create the retry subtest subtest := &retrySubtest{T: t, name: testName} - err := subtest.create(host, map[string][]string{ + subtest.create(host, map[string][]string{ method.Name: instructions.Instructions, }) - if err != nil { - t.Fatalf("setting up retry test: %v", err) - } // Create necessary test resources in the emulator fs := &resources{} @@ -179,14 +176,10 @@ func TestRetryConformance(t *testing.T) { // Verify that all instructions were used up during the test // (indicates that the client sent the correct requests). - if err := subtest.check(); err != nil { - t.Errorf("checking instructions: %v", err) - } + subtest.check() // Close out test in emulator. - if err := subtest.delete(); err != nil { - t.Errorf("deleting retry test: %v", err) - } + subtest.delete() }) } @@ -205,11 +198,11 @@ type retrySubtest struct { wrappedClient *Client } -// Create a retry test resource in the emulator -func (rt *retrySubtest) create(host string, instructions map[string][]string) error { +// create creates a retry test resource in the emulator +func (rt *retrySubtest) create(host string, instructions map[string][]string) { endpoint, err := parseURL(host) if err != nil { - return err + rt.Fatalf("setting up retry test: %v", err) } rt.host = endpoint @@ -222,13 +215,13 @@ func (rt *retrySubtest) create(host string, instructions map[string][]string) er buf := new(bytes.Buffer) if err := json.NewEncoder(buf).Encode(data); err != nil { - return fmt.Errorf("encoding request: %v", err) + rt.Fatalf("encoding request: %v", err) } rt.host.Path = "retry_test" resp, err := c.Post(rt.host.String(), "application/json", buf) if err != nil || resp.StatusCode != 200 { - return fmt.Errorf("creating retry test: err: %v, resp: %+v", err, resp) + rt.Fatalf("creating retry test: err: %v, resp: %+v", err, resp) } defer func() { closeErr := resp.Body.Close() @@ -240,7 +233,7 @@ func (rt *retrySubtest) create(host string, instructions map[string][]string) er TestID string `json:"id"` }{} if err := json.NewDecoder(resp.Body).Decode(&testRes); err != nil { - return fmt.Errorf("decoding test ID: %v", err) + rt.Fatalf("decoding test ID: %v", err) } rt.id = testRes.TestID @@ -249,20 +242,18 @@ func (rt *retrySubtest) create(host string, instructions map[string][]string) er rt.host.Path = "" client, err := wrappedClient(rt.T, rt.host.String(), rt.id) if err != nil { - return fmt.Errorf("creating wrapped client: %v", err) + rt.Fatalf("creating wrapped client: %v", err) } rt.wrappedClient = client - - return nil } // Verify that all instructions for a given retry testID have been used up. -func (rt *retrySubtest) check() error { +func (rt *retrySubtest) check() { rt.host.Path = strings.Join([]string{"retry_test", rt.id}, "/") c := http.DefaultClient resp, err := c.Get(rt.host.String()) if err != nil || resp.StatusCode != 200 { - return fmt.Errorf("getting retry test: err: %v, resp: %+v", err, resp) + rt.Errorf("getting retry test: err: %v, resp: %+v", err, resp) } defer func() { closeErr := resp.Body.Close() @@ -275,27 +266,25 @@ func (rt *retrySubtest) check() error { Completed bool }{} if err := json.NewDecoder(resp.Body).Decode(&testRes); err != nil { - return fmt.Errorf("decoding response: %v", err) + rt.Errorf("decoding response: %v", err) } if !testRes.Completed { - return fmt.Errorf("test not completed; unused instructions: %+v", testRes.Instructions) + rt.Errorf("test not completed; unused instructions: %+v", testRes.Instructions) } - return nil } // Delete a retry test resource. -func (rt *retrySubtest) delete() error { +func (rt *retrySubtest) delete() { rt.host.Path = strings.Join([]string{"retry_test", rt.id}, "/") c := http.DefaultClient req, err := http.NewRequest("DELETE", rt.host.String(), nil) if err != nil { - return fmt.Errorf("creating request: %v", err) + rt.Errorf("creating request: %v", err) } resp, err := c.Do(req) if err != nil || resp.StatusCode != 200 { - return fmt.Errorf("deleting test: err: %v, resp: %+v", err, resp) + rt.Errorf("deleting test: err: %v, resp: %+v", err, resp) } - return nil } type testRoundTripper struct { From 4e4c1f8dfb167a1e556de25ab680391dc865d237 Mon Sep 17 00:00:00 2001 From: Brenna Epp Date: Wed, 29 Sep 2021 18:19:25 -0500 Subject: [PATCH 20/25] add comments and remove extra url parsing --- storage/conformance_test.go | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/storage/conformance_test.go b/storage/conformance_test.go index f8fee301a37..1090dcd3faf 100644 --- a/storage/conformance_test.go +++ b/storage/conformance_test.go @@ -129,6 +129,10 @@ func TestRetryConformance(t *testing.T) { // TODO: Add test to CI t.Skip("This test must use the testbench emulator; set STORAGE_EMULATOR_HOST to run.") } + endpoint, err := url.Parse(host) + if err != nil { + t.Fatalf("error parsing emulator host (make sure it includes the scheme such as http://host): %v", err) + } ctx := context.Background() @@ -152,8 +156,8 @@ func TestRetryConformance(t *testing.T) { t.Run(testName, func(t *testing.T) { // Create the retry subtest - subtest := &retrySubtest{T: t, name: testName} - subtest.create(host, map[string][]string{ + subtest := &retrySubtest{T: t, name: testName, host: endpoint} + subtest.create(map[string][]string{ method.Name: instructions.Instructions, }) @@ -199,13 +203,7 @@ type retrySubtest struct { } // create creates a retry test resource in the emulator -func (rt *retrySubtest) create(host string, instructions map[string][]string) { - endpoint, err := parseURL(host) - if err != nil { - rt.Fatalf("setting up retry test: %v", err) - } - rt.host = endpoint - +func (rt *retrySubtest) create(instructions map[string][]string) { c := http.DefaultClient data := struct { Instructions map[string][]string `json:"instructions"` @@ -247,7 +245,7 @@ func (rt *retrySubtest) create(host string, instructions map[string][]string) { rt.wrappedClient = client } -// Verify that all instructions for a given retry testID have been used up. +// check verifies that all instructions for a given retry testID have been used up func (rt *retrySubtest) check() { rt.host.Path = strings.Join([]string{"retry_test", rt.id}, "/") c := http.DefaultClient @@ -287,13 +285,14 @@ func (rt *retrySubtest) delete() { } } -type testRoundTripper struct { +// retryTestRoundTripper sends the retry test ID to the emulator with each request +type retryTestRoundTripper struct { *testing.T rt http.RoundTripper testID string } -func (wt *testRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) { +func (wt *retryTestRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) { r.Header.Set("x-retry-test-id", wt.testID) requestDump, err := httputil.DumpRequest(r, false) @@ -308,7 +307,7 @@ func (wt *testRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) { return resp, err } -// Create custom client that sends instruction +// Create custom client that sends instructions to the storage testbench Retry Test API func wrappedClient(t *testing.T, host, testID string) (*Client, error) { ctx := context.Background() base := http.DefaultTransport @@ -320,7 +319,7 @@ func wrappedClient(t *testing.T, host, testID string) (*Client, error) { c := http.Client{Transport: trans} // Add RoundTripper to the created HTTP client - wrappedTrans := &testRoundTripper{rt: c.Transport, testID: testID, T: t} + wrappedTrans := &retryTestRoundTripper{rt: c.Transport, testID: testID, T: t} c.Transport = wrappedTrans // Supply this client to storage.NewClient From c157162fbda84b9e8d2f47a3efd5bdca394f3967 Mon Sep 17 00:00:00 2001 From: Brenna Epp Date: Fri, 8 Oct 2021 11:12:37 -0700 Subject: [PATCH 21/25] retry json align --- storage/internal/test/conformance/retry_tests.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/storage/internal/test/conformance/retry_tests.json b/storage/internal/test/conformance/retry_tests.json index 2e02ac115f3..0fe11477591 100644 --- a/storage/internal/test/conformance/retry_tests.json +++ b/storage/internal/test/conformance/retry_tests.json @@ -23,15 +23,15 @@ {"name": "storage.buckets.insert", "resources": []}, {"name": "storage.buckets.list", "resources": ["BUCKET"]}, {"name": "storage.buckets.lockRetentionPolicy", "resources": ["BUCKET"]}, - {"name": "storage.buckets.testIamPermissions", "resources": ["BUCKET"]}, + {"name": "storage.buckets.testIamPermissions", "resources": ["BUCKET"]}, {"name": "storage.default_object_acl.get", "resources": ["BUCKET"]}, {"name": "storage.default_object_acl.list", "resources": ["BUCKET"]}, {"name": "storage.hmacKey.delete", "resources": ["HMAC_KEY"]}, {"name": "storage.hmacKey.get", "resources": ["HMAC_KEY"]}, - {"name": "storage.hmacKey.list", "resources": []}, - {"name": "storage.notifications.delete", "resources": ["BUCKET", "NOTIFICATION"]}, - {"name": "storage.notifications.get", "resources": ["BUCKET", "NOTIFICATION"]}, - {"name": "storage.notifications.list", "resources": ["BUCKET", "NOTIFICATION"]}, + {"name": "storage.hmacKey.list", "resources": ["HMAC_KEY"]}, + {"name": "storage.notifications.delete", "resources": ["BUCKET", "NOTIFICATION"]}, + {"name": "storage.notifications.get", "resources": ["BUCKET", "NOTIFICATION"]}, + {"name": "storage.notifications.list", "resources": ["BUCKET", "NOTIFICATION"]}, {"name": "storage.object_acl.get", "resources": ["BUCKET", "OBJECT"]}, {"name": "storage.object_acl.list", "resources": ["BUCKET", "OBJECT"]}, {"name": "storage.objects.get", "resources": ["BUCKET", "OBJECT"]}, From 31744de62817702a41acdcfe7f75d89ea87b16b6 Mon Sep 17 00:00:00 2001 From: Brenna Epp Date: Fri, 8 Oct 2021 13:54:35 -0700 Subject: [PATCH 22/25] goimports fix --- storage/internal/test/conformance/test.pb.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/storage/internal/test/conformance/test.pb.go b/storage/internal/test/conformance/test.pb.go index 5d42e4b32ed..2ff5a7e9abb 100644 --- a/storage/internal/test/conformance/test.pb.go +++ b/storage/internal/test/conformance/test.pb.go @@ -10,7 +10,7 @@ // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and -// limitations under the License. +// limitations under the License // Code generated by protoc-gen-go. DO NOT EDIT. // versions: @@ -21,11 +21,12 @@ package v1 import ( + reflect "reflect" + sync "sync" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" timestamppb "google.golang.org/protobuf/types/known/timestamppb" - reflect "reflect" - sync "sync" ) const ( From 8d1ecfb5148ea8a579697e89a1ea4cf5542e54fa Mon Sep 17 00:00:00 2001 From: Brenna Epp Date: Fri, 8 Oct 2021 15:06:25 -0700 Subject: [PATCH 23/25] remove extra func --- storage/conformance_test.go | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/storage/conformance_test.go b/storage/conformance_test.go index 1090dcd3faf..5fa75f342ba 100644 --- a/storage/conformance_test.go +++ b/storage/conformance_test.go @@ -327,18 +327,6 @@ func wrappedClient(t *testing.T, host, testID string) (*Client, error) { return client, err } -// A url is only parsed correctly by the url package if it has a scheme, -// so we have to check and build it ourselves if not supplied in host -// Assumes http if not provided -func parseURL(host string) (*url.URL, error) { - if strings.Contains(host, "://") { - return url.Parse(host) - } else { - url := &url.URL{Scheme: "http", Host: host} - return url, nil - } -} - func TestPostPolicyV4Conformance(t *testing.T) { oldUTCNow := utcNow defer func() { From ed848c200cd682e31082039093d3b7c94cac949f Mon Sep 17 00:00:00 2001 From: Brenna Epp Date: Mon, 18 Oct 2021 14:21:37 -0700 Subject: [PATCH 24/25] separate retry tests --- storage/conformance_test.go | 296 --------------------------- storage/retry_conformance_test.go | 324 ++++++++++++++++++++++++++++++ 2 files changed, 324 insertions(+), 296 deletions(-) create mode 100644 storage/retry_conformance_test.go diff --git a/storage/conformance_test.go b/storage/conformance_test.go index 5fa75f342ba..bf26c9515ae 100644 --- a/storage/conformance_test.go +++ b/storage/conformance_test.go @@ -16,317 +16,21 @@ package storage import ( "bytes" - "context" "encoding/base64" "encoding/json" "fmt" "io/ioutil" - "net/http" - "net/http/httputil" "net/url" - "os" "strconv" "strings" "testing" "time" - "cloud.google.com/go/internal/uid" storage_v1_tests "cloud.google.com/go/storage/internal/test/conformance" "github.com/golang/protobuf/jsonpb" "github.com/google/go-cmp/cmp" - "google.golang.org/api/option" - raw "google.golang.org/api/storage/v1" - htransport "google.golang.org/api/transport/http" ) -var ( - // Resource vars for retry tests - bucketIDs = uid.NewSpace("bucket", nil) - objectIDs = uid.NewSpace("object", nil) - notificationIDs = uid.NewSpace("notification", nil) - projectID = "my-project-id" - serviceAccountEmail = "my-sevice-account@my-project-id.iam.gserviceaccount.com" - randomBytesToWrite = []byte("abcdef") -) - -// Holds the resources for a particular test case. Only the necessary fields will -// be populated; others will be nil. -type resources struct { - bucket *BucketAttrs - object *ObjectAttrs - notification *Notification - hmacKey *HMACKey -} - -func (fs *resources) populate(ctx context.Context, c *Client, resource storage_v1_tests.Resource) error { - switch resource { - case storage_v1_tests.Resource_BUCKET: - bkt := c.Bucket(bucketIDs.New()) - if err := bkt.Create(ctx, projectID, &BucketAttrs{}); err != nil { - return fmt.Errorf("creating bucket: %v", err) - } - attrs, err := bkt.Attrs(ctx) - if err != nil { - return fmt.Errorf("getting bucket attrs: %v", err) - } - fs.bucket = attrs - case storage_v1_tests.Resource_OBJECT: - // Assumes bucket has been populated first. - obj := c.Bucket(fs.bucket.Name).Object(objectIDs.New()) - w := obj.NewWriter(ctx) - if _, err := w.Write(randomBytesToWrite); err != nil { - return fmt.Errorf("writing object: %v", err) - } - if err := w.Close(); err != nil { - return fmt.Errorf("closing object: %v", err) - } - attrs, err := obj.Attrs(ctx) - if err != nil { - return fmt.Errorf("getting object attrs: %v", err) - } - fs.object = attrs - case storage_v1_tests.Resource_NOTIFICATION: - // Assumes bucket has been populated first. - n, err := c.Bucket(fs.bucket.Name).AddNotification(ctx, &Notification{ - TopicProjectID: projectID, - TopicID: notificationIDs.New(), - PayloadFormat: JSONPayload, - }) - if err != nil { - return fmt.Errorf("adding notification: %v", err) - } - fs.notification = n - case storage_v1_tests.Resource_HMAC_KEY: - key, err := c.CreateHMACKey(ctx, projectID, serviceAccountEmail) - if err != nil { - return fmt.Errorf("creating HMAC key: %v", err) - } - fs.hmacKey = key - } - return nil -} - -type retryFunc func(ctx context.Context, c *Client, fs *resources, preconditions bool) error - -// Methods to retry. This is a map whose keys are a string describing a standard -// API call (e.g. storage.objects.get) and values are a list of functions which -// wrap library methods that implement these calls. There may be multiple values -// because multiple library methods may use the same call (e.g. get could be a -// read or just a metadata get). -var methods = map[string][]retryFunc{ - "storage.buckets.get": { - func(ctx context.Context, c *Client, fs *resources, _ bool) error { - _, err := c.Bucket(fs.bucket.Name).Attrs(ctx) - return err - }, - }, -} - -func TestRetryConformance(t *testing.T) { - host := os.Getenv("STORAGE_EMULATOR_HOST") - if host == "" { - // This test is currently skipped in CI as the env variable is not set - // TODO: Add test to CI - t.Skip("This test must use the testbench emulator; set STORAGE_EMULATOR_HOST to run.") - } - endpoint, err := url.Parse(host) - if err != nil { - t.Fatalf("error parsing emulator host (make sure it includes the scheme such as http://host): %v", err) - } - - ctx := context.Background() - - // Create non-wrapped client to use for setup steps. - client, err := NewClient(ctx) - if err != nil { - t.Fatalf("storage.NewClient: %v", err) - } - - _, _, testFiles := parseFiles(t) - - for _, testFile := range testFiles { - for _, retryTest := range testFile.RetryTests { - for _, instructions := range retryTest.Cases { - for _, method := range retryTest.Methods { - if len(methods[method.Name]) == 0 { - t.Logf("No tests for operation %v", method.Name) - } - for i, fn := range methods[method.Name] { - testName := fmt.Sprintf("%v-%v-%v-%v", retryTest.Id, instructions.Instructions, method.Name, i) - t.Run(testName, func(t *testing.T) { - - // Create the retry subtest - subtest := &retrySubtest{T: t, name: testName, host: endpoint} - subtest.create(map[string][]string{ - method.Name: instructions.Instructions, - }) - - // Create necessary test resources in the emulator - fs := &resources{} - for _, resource := range method.Resources { - if err := fs.populate(ctx, client, resource); err != nil { - t.Fatalf("creating test resources: %v", err) - } - } - - // Test - err = fn(ctx, subtest.wrappedClient, fs, retryTest.PreconditionProvided) - if retryTest.ExpectSuccess && err != nil { - t.Errorf("want success, got %v", err) - } - if !retryTest.ExpectSuccess && err == nil { - t.Errorf("want failure, got success") - } - - // Verify that all instructions were used up during the test - // (indicates that the client sent the correct requests). - subtest.check() - - // Close out test in emulator. - subtest.delete() - }) - } - - } - } - } - } - -} - -type retrySubtest struct { - *testing.T - name string - id string // ID to pass as a header in the test execution - host *url.URL // set the path when using; path is not guaranteed betwen calls - wrappedClient *Client -} - -// create creates a retry test resource in the emulator -func (rt *retrySubtest) create(instructions map[string][]string) { - c := http.DefaultClient - data := struct { - Instructions map[string][]string `json:"instructions"` - }{ - Instructions: instructions, - } - - buf := new(bytes.Buffer) - if err := json.NewEncoder(buf).Encode(data); err != nil { - rt.Fatalf("encoding request: %v", err) - } - - rt.host.Path = "retry_test" - resp, err := c.Post(rt.host.String(), "application/json", buf) - if err != nil || resp.StatusCode != 200 { - rt.Fatalf("creating retry test: err: %v, resp: %+v", err, resp) - } - defer func() { - closeErr := resp.Body.Close() - if err == nil { - err = closeErr - } - }() - testRes := struct { - TestID string `json:"id"` - }{} - if err := json.NewDecoder(resp.Body).Decode(&testRes); err != nil { - rt.Fatalf("decoding test ID: %v", err) - } - - rt.id = testRes.TestID - - // Create wrapped client which will send emulator instructions - rt.host.Path = "" - client, err := wrappedClient(rt.T, rt.host.String(), rt.id) - if err != nil { - rt.Fatalf("creating wrapped client: %v", err) - } - rt.wrappedClient = client -} - -// check verifies that all instructions for a given retry testID have been used up -func (rt *retrySubtest) check() { - rt.host.Path = strings.Join([]string{"retry_test", rt.id}, "/") - c := http.DefaultClient - resp, err := c.Get(rt.host.String()) - if err != nil || resp.StatusCode != 200 { - rt.Errorf("getting retry test: err: %v, resp: %+v", err, resp) - } - defer func() { - closeErr := resp.Body.Close() - if err == nil { - err = closeErr - } - }() - testRes := struct { - Instructions map[string][]string - Completed bool - }{} - if err := json.NewDecoder(resp.Body).Decode(&testRes); err != nil { - rt.Errorf("decoding response: %v", err) - } - if !testRes.Completed { - rt.Errorf("test not completed; unused instructions: %+v", testRes.Instructions) - } -} - -// Delete a retry test resource. -func (rt *retrySubtest) delete() { - rt.host.Path = strings.Join([]string{"retry_test", rt.id}, "/") - c := http.DefaultClient - req, err := http.NewRequest("DELETE", rt.host.String(), nil) - if err != nil { - rt.Errorf("creating request: %v", err) - } - resp, err := c.Do(req) - if err != nil || resp.StatusCode != 200 { - rt.Errorf("deleting test: err: %v, resp: %+v", err, resp) - } -} - -// retryTestRoundTripper sends the retry test ID to the emulator with each request -type retryTestRoundTripper struct { - *testing.T - rt http.RoundTripper - testID string -} - -func (wt *retryTestRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) { - r.Header.Set("x-retry-test-id", wt.testID) - - requestDump, err := httputil.DumpRequest(r, false) - if err != nil { - wt.Logf("error creating request dump: %v", err) - } - - resp, err := wt.rt.RoundTrip(r) - if err != nil { - wt.Logf("roundtrip error (may be expected): %v\nrequest: %s", err, requestDump) - } - return resp, err -} - -// Create custom client that sends instructions to the storage testbench Retry Test API -func wrappedClient(t *testing.T, host, testID string) (*Client, error) { - ctx := context.Background() - base := http.DefaultTransport - trans, err := htransport.NewTransport(ctx, base, option.WithScopes(raw.DevstorageFullControlScope), - option.WithUserAgent("custom-user-agent")) - if err != nil { - return nil, fmt.Errorf("failed to create http client: %v", err) - } - c := http.Client{Transport: trans} - - // Add RoundTripper to the created HTTP client - wrappedTrans := &retryTestRoundTripper{rt: c.Transport, testID: testID, T: t} - c.Transport = wrappedTrans - - // Supply this client to storage.NewClient - client, err := NewClient(ctx, option.WithHTTPClient(&c), option.WithEndpoint(host+"/storage/v1/")) - return client, err -} - func TestPostPolicyV4Conformance(t *testing.T) { oldUTCNow := utcNow defer func() { diff --git a/storage/retry_conformance_test.go b/storage/retry_conformance_test.go new file mode 100644 index 00000000000..eee48d13aa4 --- /dev/null +++ b/storage/retry_conformance_test.go @@ -0,0 +1,324 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package storage + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "net/http" + "net/http/httputil" + "net/url" + "os" + "strings" + "testing" + + "cloud.google.com/go/internal/uid" + storage_v1_tests "cloud.google.com/go/storage/internal/test/conformance" + "google.golang.org/api/option" + raw "google.golang.org/api/storage/v1" + htransport "google.golang.org/api/transport/http" +) + +var ( + // Resource vars for retry tests + bucketIDs = uid.NewSpace("bucket", nil) + objectIDs = uid.NewSpace("object", nil) + notificationIDs = uid.NewSpace("notification", nil) + projectID = "my-project-id" + serviceAccountEmail = "my-sevice-account@my-project-id.iam.gserviceaccount.com" + randomBytesToWrite = []byte("abcdef") +) + +type retryFunc func(ctx context.Context, c *Client, fs *resources, preconditions bool) error + +// Methods to retry. This is a map whose keys are a string describing a standard +// API call (e.g. storage.objects.get) and values are a list of functions which +// wrap library methods that implement these calls. There may be multiple values +// because multiple library methods may use the same call (e.g. get could be a +// read or just a metadata get). +var methods = map[string][]retryFunc{ + "storage.buckets.get": { + func(ctx context.Context, c *Client, fs *resources, _ bool) error { + _, err := c.Bucket(fs.bucket.Name).Attrs(ctx) + return err + }, + }, +} + +func TestRetryConformance(t *testing.T) { + //appCreds := os.Getenv("GOOGLE_APPLICATION_CREDENTIALS") + // os.Unsetenv("GOOGLE_CLOUD_PROJECT") + // os.Unsetenv("GOOGLE_APPLICATION_CREDENTIALS") + // defer os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", appCreds) + //os.Setenv("STORAGE_EMULATOR_HOST", "http://localhost:9000") + host := os.Getenv("STORAGE_EMULATOR_HOST") + if host == "" { + // This test is currently skipped in CI as the env variable is not set + // TODO: Add test to CI + t.Skip("This test must use the testbench emulator; set STORAGE_EMULATOR_HOST to run.") + } + endpoint, err := url.Parse(host) + if err != nil { + t.Fatalf("error parsing emulator host (make sure it includes the scheme such as http://host): %v", err) + } + + ctx := context.Background() + + // Create non-wrapped client to use for setup steps. + client, err := NewClient(ctx) + if err != nil { + t.Fatalf("storage.NewClient: %v", err) + } + + _, _, testFiles := parseFiles(t) + + for _, testFile := range testFiles { + for _, retryTest := range testFile.RetryTests { + for _, instructions := range retryTest.Cases { + for _, method := range retryTest.Methods { + if len(methods[method.Name]) == 0 { + t.Logf("No tests for operation %v", method.Name) + } + for i, fn := range methods[method.Name] { + testName := fmt.Sprintf("%v-%v-%v-%v", retryTest.Id, instructions.Instructions, method.Name, i) + t.Run(testName, func(t *testing.T) { + + // Create the retry subtest + subtest := &retrySubtest{T: t, name: testName, host: endpoint} + subtest.create(map[string][]string{ + method.Name: instructions.Instructions, + }) + + // Create necessary test resources in the emulator + subtest.populateResources(ctx, client, method.Resources) + + // Test + err = fn(ctx, subtest.wrappedClient, &subtest.resources, retryTest.PreconditionProvided) + if retryTest.ExpectSuccess && err != nil { + t.Errorf("want success, got %v", err) + } + if !retryTest.ExpectSuccess && err == nil { + t.Errorf("want failure, got success") + } + + // Verify that all instructions were used up during the test + // (indicates that the client sent the correct requests). + subtest.check() + + // Close out test in emulator. + subtest.delete() + }) + } + + } + } + } + } + +} + +type retrySubtest struct { + *testing.T + name string + id string // ID to pass as a header in the test execution + resources resources + host *url.URL // set the path when using; path is not guaranteed betwen calls + wrappedClient *Client +} + +// Holds the resources for a particular test case. Only the necessary fields will +// be populated; others will be nil. +type resources struct { + bucket *BucketAttrs + object *ObjectAttrs + notification *Notification + hmacKey *HMACKey +} + +func (rt *retrySubtest) populateResources(ctx context.Context, c *Client, resources []storage_v1_tests.Resource) { + for _, resource := range resources { + switch resource { + case storage_v1_tests.Resource_BUCKET: + bkt := c.Bucket(bucketIDs.New()) + if err := bkt.Create(ctx, projectID, &BucketAttrs{}); err != nil { + rt.Fatalf("creating bucket: %v", err) + } + attrs, err := bkt.Attrs(ctx) + if err != nil { + rt.Fatalf("getting bucket attrs: %v", err) + } + rt.resources.bucket = attrs + case storage_v1_tests.Resource_OBJECT: + // Assumes bucket has been populated first. + obj := c.Bucket(rt.resources.bucket.Name).Object(objectIDs.New()) + w := obj.NewWriter(ctx) + if _, err := w.Write(randomBytesToWrite); err != nil { + rt.Fatalf("writing object: %v", err) + } + if err := w.Close(); err != nil { + rt.Fatalf("closing object: %v", err) + } + attrs, err := obj.Attrs(ctx) + if err != nil { + rt.Fatalf("getting object attrs: %v", err) + } + rt.resources.object = attrs + case storage_v1_tests.Resource_NOTIFICATION: + // Assumes bucket has been populated first. + n, err := c.Bucket(rt.resources.bucket.Name).AddNotification(ctx, &Notification{ + TopicProjectID: projectID, + TopicID: notificationIDs.New(), + PayloadFormat: JSONPayload, + }) + if err != nil { + rt.Fatalf("adding notification: %v", err) + } + rt.resources.notification = n + case storage_v1_tests.Resource_HMAC_KEY: + key, err := c.CreateHMACKey(ctx, projectID, serviceAccountEmail) + if err != nil { + rt.Fatalf("creating HMAC key: %v", err) + } + rt.resources.hmacKey = key + } + } +} + +// create creates a retry test resource in the emulator +func (rt *retrySubtest) create(instructions map[string][]string) { + c := http.DefaultClient + data := struct { + Instructions map[string][]string `json:"instructions"` + }{ + Instructions: instructions, + } + + buf := new(bytes.Buffer) + if err := json.NewEncoder(buf).Encode(data); err != nil { + rt.Fatalf("encoding request: %v", err) + } + + rt.host.Path = "retry_test" + resp, err := c.Post(rt.host.String(), "application/json", buf) + if err != nil || resp.StatusCode != 200 { + rt.Fatalf("creating retry test: err: %v, resp: %+v", err, resp) + } + defer func() { + closeErr := resp.Body.Close() + if err == nil { + err = closeErr + } + }() + testRes := struct { + TestID string `json:"id"` + }{} + if err := json.NewDecoder(resp.Body).Decode(&testRes); err != nil { + rt.Fatalf("decoding test ID: %v", err) + } + + rt.id = testRes.TestID + + // Create wrapped client which will send emulator instructions + rt.host.Path = "" + client, err := wrappedClient(rt.T, rt.host.String(), rt.id) + if err != nil { + rt.Fatalf("creating wrapped client: %v", err) + } + rt.wrappedClient = client +} + +// check verifies that all instructions for a given retry testID have been used up +func (rt *retrySubtest) check() { + rt.host.Path = strings.Join([]string{"retry_test", rt.id}, "/") + c := http.DefaultClient + resp, err := c.Get(rt.host.String()) + if err != nil || resp.StatusCode != 200 { + rt.Errorf("getting retry test: err: %v, resp: %+v", err, resp) + } + defer func() { + closeErr := resp.Body.Close() + if err == nil { + err = closeErr + } + }() + testRes := struct { + Instructions map[string][]string + Completed bool + }{} + if err := json.NewDecoder(resp.Body).Decode(&testRes); err != nil { + rt.Errorf("decoding response: %v", err) + } + if !testRes.Completed { + rt.Errorf("test not completed; unused instructions: %+v", testRes.Instructions) + } +} + +// Delete a retry test resource. +func (rt *retrySubtest) delete() { + rt.host.Path = strings.Join([]string{"retry_test", rt.id}, "/") + c := http.DefaultClient + req, err := http.NewRequest("DELETE", rt.host.String(), nil) + if err != nil { + rt.Errorf("creating request: %v", err) + } + resp, err := c.Do(req) + if err != nil || resp.StatusCode != 200 { + rt.Errorf("deleting test: err: %v, resp: %+v", err, resp) + } +} + +// retryTestRoundTripper sends the retry test ID to the emulator with each request +type retryTestRoundTripper struct { + *testing.T + rt http.RoundTripper + testID string +} + +func (wt *retryTestRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) { + r.Header.Set("x-retry-test-id", wt.testID) + + requestDump, err := httputil.DumpRequest(r, false) + if err != nil { + wt.Logf("error creating request dump: %v", err) + } + + resp, err := wt.rt.RoundTrip(r) + if err != nil { + wt.Logf("roundtrip error (may be expected): %v\nrequest: %s", err, requestDump) + } + return resp, err +} + +// Create custom client that sends instructions to the storage testbench Retry Test API +func wrappedClient(t *testing.T, host, testID string) (*Client, error) { + ctx := context.Background() + base := http.DefaultTransport + trans, err := htransport.NewTransport(ctx, base, option.WithScopes(raw.DevstorageFullControlScope), + option.WithUserAgent("custom-user-agent")) + if err != nil { + return nil, fmt.Errorf("failed to create http client: %v", err) + } + c := http.Client{Transport: trans} + + // Add RoundTripper to the created HTTP client + wrappedTrans := &retryTestRoundTripper{rt: c.Transport, testID: testID, T: t} + c.Transport = wrappedTrans + + // Supply this client to storage.NewClient + client, err := NewClient(ctx, option.WithHTTPClient(&c), option.WithEndpoint(host+"/storage/v1/")) + return client, err +} From acdd4464608e839abcd83fd48bd720d8b4934c2d Mon Sep 17 00:00:00 2001 From: Brenna Epp Date: Mon, 18 Oct 2021 14:56:26 -0700 Subject: [PATCH 25/25] fix typos --- storage/retry_conformance_test.go | 92 +++++++++++++++---------------- 1 file changed, 43 insertions(+), 49 deletions(-) diff --git a/storage/retry_conformance_test.go b/storage/retry_conformance_test.go index eee48d13aa4..894fb5fad09 100644 --- a/storage/retry_conformance_test.go +++ b/storage/retry_conformance_test.go @@ -60,11 +60,6 @@ var methods = map[string][]retryFunc{ } func TestRetryConformance(t *testing.T) { - //appCreds := os.Getenv("GOOGLE_APPLICATION_CREDENTIALS") - // os.Unsetenv("GOOGLE_CLOUD_PROJECT") - // os.Unsetenv("GOOGLE_APPLICATION_CREDENTIALS") - // defer os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", appCreds) - //os.Setenv("STORAGE_EMULATOR_HOST", "http://localhost:9000") host := os.Getenv("STORAGE_EMULATOR_HOST") if host == "" { // This test is currently skipped in CI as the env variable is not set @@ -98,7 +93,7 @@ func TestRetryConformance(t *testing.T) { t.Run(testName, func(t *testing.T) { // Create the retry subtest - subtest := &retrySubtest{T: t, name: testName, host: endpoint} + subtest := &emulatorTest{T: t, name: testName, host: endpoint} subtest.create(map[string][]string{ method.Name: instructions.Instructions, }) @@ -123,20 +118,18 @@ func TestRetryConformance(t *testing.T) { subtest.delete() }) } - } } } } - } -type retrySubtest struct { +type emulatorTest struct { *testing.T name string id string // ID to pass as a header in the test execution resources resources - host *url.URL // set the path when using; path is not guaranteed betwen calls + host *url.URL // set the path when using; path is not guaranteed between calls wrappedClient *Client } @@ -149,57 +142,58 @@ type resources struct { hmacKey *HMACKey } -func (rt *retrySubtest) populateResources(ctx context.Context, c *Client, resources []storage_v1_tests.Resource) { +// Creates given test resources with the provided client +func (et *emulatorTest) populateResources(ctx context.Context, c *Client, resources []storage_v1_tests.Resource) { for _, resource := range resources { switch resource { case storage_v1_tests.Resource_BUCKET: bkt := c.Bucket(bucketIDs.New()) if err := bkt.Create(ctx, projectID, &BucketAttrs{}); err != nil { - rt.Fatalf("creating bucket: %v", err) + et.Fatalf("creating bucket: %v", err) } attrs, err := bkt.Attrs(ctx) if err != nil { - rt.Fatalf("getting bucket attrs: %v", err) + et.Fatalf("getting bucket attrs: %v", err) } - rt.resources.bucket = attrs + et.resources.bucket = attrs case storage_v1_tests.Resource_OBJECT: // Assumes bucket has been populated first. - obj := c.Bucket(rt.resources.bucket.Name).Object(objectIDs.New()) + obj := c.Bucket(et.resources.bucket.Name).Object(objectIDs.New()) w := obj.NewWriter(ctx) if _, err := w.Write(randomBytesToWrite); err != nil { - rt.Fatalf("writing object: %v", err) + et.Fatalf("writing object: %v", err) } if err := w.Close(); err != nil { - rt.Fatalf("closing object: %v", err) + et.Fatalf("closing object: %v", err) } attrs, err := obj.Attrs(ctx) if err != nil { - rt.Fatalf("getting object attrs: %v", err) + et.Fatalf("getting object attrs: %v", err) } - rt.resources.object = attrs + et.resources.object = attrs case storage_v1_tests.Resource_NOTIFICATION: // Assumes bucket has been populated first. - n, err := c.Bucket(rt.resources.bucket.Name).AddNotification(ctx, &Notification{ + n, err := c.Bucket(et.resources.bucket.Name).AddNotification(ctx, &Notification{ TopicProjectID: projectID, TopicID: notificationIDs.New(), PayloadFormat: JSONPayload, }) if err != nil { - rt.Fatalf("adding notification: %v", err) + et.Fatalf("adding notification: %v", err) } - rt.resources.notification = n + et.resources.notification = n case storage_v1_tests.Resource_HMAC_KEY: key, err := c.CreateHMACKey(ctx, projectID, serviceAccountEmail) if err != nil { - rt.Fatalf("creating HMAC key: %v", err) + et.Fatalf("creating HMAC key: %v", err) } - rt.resources.hmacKey = key + et.resources.hmacKey = key } } } -// create creates a retry test resource in the emulator -func (rt *retrySubtest) create(instructions map[string][]string) { +// Creates a retry test resource in the emulator +func (et *emulatorTest) create(instructions map[string][]string) { c := http.DefaultClient data := struct { Instructions map[string][]string `json:"instructions"` @@ -209,13 +203,13 @@ func (rt *retrySubtest) create(instructions map[string][]string) { buf := new(bytes.Buffer) if err := json.NewEncoder(buf).Encode(data); err != nil { - rt.Fatalf("encoding request: %v", err) + et.Fatalf("encoding request: %v", err) } - rt.host.Path = "retry_test" - resp, err := c.Post(rt.host.String(), "application/json", buf) + et.host.Path = "retry_test" + resp, err := c.Post(et.host.String(), "application/json", buf) if err != nil || resp.StatusCode != 200 { - rt.Fatalf("creating retry test: err: %v, resp: %+v", err, resp) + et.Fatalf("creating retry test: err: %v, resp: %+v", err, resp) } defer func() { closeErr := resp.Body.Close() @@ -227,27 +221,27 @@ func (rt *retrySubtest) create(instructions map[string][]string) { TestID string `json:"id"` }{} if err := json.NewDecoder(resp.Body).Decode(&testRes); err != nil { - rt.Fatalf("decoding test ID: %v", err) + et.Fatalf("decoding test ID: %v", err) } - rt.id = testRes.TestID + et.id = testRes.TestID // Create wrapped client which will send emulator instructions - rt.host.Path = "" - client, err := wrappedClient(rt.T, rt.host.String(), rt.id) + et.host.Path = "" + client, err := wrappedClient(et.T, et.host.String(), et.id) if err != nil { - rt.Fatalf("creating wrapped client: %v", err) + et.Fatalf("creating wrapped client: %v", err) } - rt.wrappedClient = client + et.wrappedClient = client } -// check verifies that all instructions for a given retry testID have been used up -func (rt *retrySubtest) check() { - rt.host.Path = strings.Join([]string{"retry_test", rt.id}, "/") +// Verifies that all instructions for a given retry testID have been used up +func (et *emulatorTest) check() { + et.host.Path = strings.Join([]string{"retry_test", et.id}, "/") c := http.DefaultClient - resp, err := c.Get(rt.host.String()) + resp, err := c.Get(et.host.String()) if err != nil || resp.StatusCode != 200 { - rt.Errorf("getting retry test: err: %v, resp: %+v", err, resp) + et.Errorf("getting retry test: err: %v, resp: %+v", err, resp) } defer func() { closeErr := resp.Body.Close() @@ -260,24 +254,24 @@ func (rt *retrySubtest) check() { Completed bool }{} if err := json.NewDecoder(resp.Body).Decode(&testRes); err != nil { - rt.Errorf("decoding response: %v", err) + et.Errorf("decoding response: %v", err) } if !testRes.Completed { - rt.Errorf("test not completed; unused instructions: %+v", testRes.Instructions) + et.Errorf("test not completed; unused instructions: %+v", testRes.Instructions) } } -// Delete a retry test resource. -func (rt *retrySubtest) delete() { - rt.host.Path = strings.Join([]string{"retry_test", rt.id}, "/") +// Deletes a retry test resource +func (et *emulatorTest) delete() { + et.host.Path = strings.Join([]string{"retry_test", et.id}, "/") c := http.DefaultClient - req, err := http.NewRequest("DELETE", rt.host.String(), nil) + req, err := http.NewRequest("DELETE", et.host.String(), nil) if err != nil { - rt.Errorf("creating request: %v", err) + et.Errorf("creating request: %v", err) } resp, err := c.Do(req) if err != nil || resp.StatusCode != 200 { - rt.Errorf("deleting test: err: %v, resp: %+v", err, resp) + et.Errorf("deleting test: err: %v, resp: %+v", err, resp) } }