Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test(storage): add test for uploading with an emulator #4641

Merged
merged 34 commits into from
Aug 30, 2021
Merged
Changes from 2 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
954b8f0
fix(storage): remove unnecessary variable
BrennaEpp Aug 13, 2021
439d22d
Merge branch 'master' of https://github.com/BrennaEpp/google-cloud-go…
BrennaEpp Aug 13, 2021
4f6b1dc
fix(storage): preserve supplied endpoint's scheme
BrennaEpp Aug 13, 2021
ad65048
fix(storage): accept emulator env var without scheme
BrennaEpp Aug 13, 2021
1ce4d79
Merge branch 'master' into add-endpoint-for-u
BrennaEpp Aug 13, 2021
dd8f1b0
Rename var
BrennaEpp Aug 13, 2021
1383d95
Fix bug
BrennaEpp Aug 13, 2021
9a24f43
Merge remote-tracking branch 'origin' into add-endpoint-for-u
BrennaEpp Aug 13, 2021
cce5ff4
Small refactorings
BrennaEpp Aug 13, 2021
627dbc8
Merge branch 'master' into add-endpoint-for-u
BrennaEpp Aug 13, 2021
b1aa377
Add test case for host:port
BrennaEpp Aug 13, 2021
8d14f45
init
BrennaEpp Aug 16, 2021
d242796
Add test
BrennaEpp Aug 18, 2021
957a6c2
Merge branch 'master' into add-emulator-ops-test
BrennaEpp Aug 18, 2021
cc0268f
fix spacing
BrennaEpp Aug 18, 2021
840a644
Merge branch 'master' into add-emulator-ops-test
BrennaEpp Aug 18, 2021
d725d23
Added check that the hit endpoint does not change
BrennaEpp Aug 19, 2021
209e3e6
Merge branch 'add-emulator-ops-test' of https://github.com/BrennaEpp/…
BrennaEpp Aug 19, 2021
725ae20
Use subtests
BrennaEpp Aug 19, 2021
76556ec
Merge branch 'master' into add-emulator-ops-test
BrennaEpp Aug 19, 2021
4714103
polish
BrennaEpp Aug 19, 2021
cfbad8a
test verifies that server receives correct calls
BrennaEpp Aug 20, 2021
e3e2685
Merge branch 'master' into add-emulator-ops-test
BrennaEpp Aug 20, 2021
05b2f4a
timeout overall in test
BrennaEpp Aug 21, 2021
98df678
timeout per subtest
BrennaEpp Aug 21, 2021
9d6b75f
Merge branch 'add-emulator-ops-test' of https://github.com/BrennaEpp/…
BrennaEpp Aug 21, 2021
c1118f2
cleanup
BrennaEpp Aug 23, 2021
48adf3c
Merge branch 'master' into add-emulator-ops-test
BrennaEpp Aug 24, 2021
889963f
Merge branch 'master' into add-emulator-ops-test
BrennaEpp Aug 24, 2021
8e688a0
Merge branch 'master' into add-emulator-ops-test
BrennaEpp Aug 27, 2021
473d82e
Merge branch 'master' into add-emulator-ops-test
BrennaEpp Aug 27, 2021
fca17d6
Merge branch 'master' into add-emulator-ops-test
BrennaEpp Aug 27, 2021
b849b6f
Merge branch 'master' into add-emulator-ops-test
BrennaEpp Aug 27, 2021
09a49ba
Merge branch 'master' into add-emulator-ops-test
BrennaEpp Aug 30, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 87 additions & 70 deletions storage/storage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1361,20 +1361,23 @@ func TestWithEndpoint(t *testing.T) {
os.Setenv("STORAGE_EMULATOR_HOST", originalStorageEmulatorHost)
}

// Create a client using a combination of custom endpoint and
// STORAGE_EMULATOR_HOST env variable and verify that raw.BasePath,
// readHost and scheme are not changed by running operations such as upload
// Create a client using a combination of custom endpoint and STORAGE_EMULATOR_HOST
// env variable and verify that the client hits the correct endpoint for several
// different operations performe in sequence.
// Verifies also that raw.BasePath, readHost and scheme are not changed
// after running the operations.
func TestOperationsWithEndpoint(t *testing.T) {
originalStorageEmulatorHost := os.Getenv("STORAGE_EMULATOR_HOST")
defer os.Setenv("STORAGE_EMULATOR_HOST", originalStorageEmulatorHost)

var lastRequestEndpoint string
gotURL := make(chan string, 1)
gotMethod := make(chan string, 1)

addr, hClient, close := newTestServerAt(func(w http.ResponseWriter, r *http.Request) {
hClient, close := newTestServer(func(w http.ResponseWriter, r *http.Request) {
io.Copy(ioutil.Discard, r.Body)
fmt.Fprintf(w, "{}")
req, _ := url.Parse(r.RequestURI)
lastRequestEndpoint = req.RawPath
gotURL <- r.RequestURI
tritone marked this conversation as resolved.
Show resolved Hide resolved
gotMethod <- r.Method
})
defer close()

Expand All @@ -1391,17 +1394,17 @@ func TestOperationsWithEndpoint(t *testing.T) {
{
desc: "emulator host specified",
CustomEndpoint: "",
StorageEmulatorHost: "https://" + addr,
StorageEmulatorHost: "https://host",
},
{
desc: "endpoint specified",
CustomEndpoint: "https://" + addr,
CustomEndpoint: "https://" + "end" + "/storage/v1/",
StorageEmulatorHost: "",
},
{
desc: "both emulator and endpoint specified",
CustomEndpoint: "https://" + addr,
StorageEmulatorHost: "https://" + addr,
CustomEndpoint: "https://" + "end" + "/storage/v1/",
StorageEmulatorHost: "https://host",
},
}
ctx := context.Background()
Expand All @@ -1417,76 +1420,90 @@ func TestOperationsWithEndpoint(t *testing.T) {
originalReadHost := c.readHost
originalScheme := c.scheme

// Create a bucket
c.Bucket("test-bucket").Create(ctx, "pid", nil)
if err != nil {
t.Errorf("%s: %v", tc.desc, err)
}
createBucketEndpoint := lastRequestEndpoint

// Upload an object
w := c.Bucket("test-bucket").Object("file").NewWriter(ctx)
_, err = io.Copy(w, strings.NewReader("copyng into bucket"))
if err != nil {
t.Errorf("%s: %v", tc.desc, err)
}
if closeErr := w.Close(); closeErr != nil {
t.Errorf("%s: %v", tc.desc, closeErr)
}

// Download an object
rc, err := c.Bucket("test-bucket").Object("file").NewReader(ctx)
if err != nil {
t.Errorf("%s: %v", tc.desc, err)
}
defer rc.Close()

_, err = io.Copy(ioutil.Discard, rc)
if err != nil {
t.Errorf("%s: %v", tc.desc, err)
}

// Delete bucket
if err := c.Bucket("test-bucket").Delete(ctx); err != nil {
t.Errorf("%s: %v", tc.desc, err)
}

// Create a bucket
c.Bucket("test-bucket").Create(ctx, "pid", nil)
if err != nil {
t.Errorf("%s: %v", tc.desc, err)
operations := []struct {
desc string
runOp func() error
wantURL string
wantMethod string
}{
{
desc: "Create a bucket",
runOp: func() error {
return c.Bucket("test-bucket").Create(ctx, "pid", nil)
},
wantURL: "/storage/v1/b?alt=json&prettyPrint=false&project=pid",
wantMethod: "POST",
},
{
desc: "Upload an object",
runOp: func() error {
w := c.Bucket("test-bucket").Object("file").NewWriter(ctx)
_, err = io.Copy(w, strings.NewReader("copyng into bucket"))
if err != nil {
return err
}
return w.Close()
},
wantURL: "/upload/storage/v1/b/test-bucket/o?alt=json&name=file&prettyPrint=false&projection=full&uploadType=multipart",
wantMethod: "POST",
},
{
desc: "Download an object",
runOp: func() error {
rc, err := c.Bucket("test-bucket").Object("file").NewReader(ctx)
if err != nil {
return err
}

_, err = io.Copy(ioutil.Discard, rc)
if err != nil {
return err
}
return rc.Close()
},
wantURL: "/test-bucket/file",
wantMethod: "GET",
},
{
desc: "Delete bucket",
runOp: func() error {
return c.Bucket("test-bucket").Delete(ctx)
},
wantURL: "/storage/v1/b/test-bucket?alt=json&prettyPrint=false",
wantMethod: "DELETE",
},
}

if lastRequestEndpoint != createBucketEndpoint {
t.Errorf("unexpected change in endpoint for creating a bucket\n\tgot:\t\t%v\n\toriginal:\t%v", lastRequestEndpoint, createBucketEndpoint)
// Check that the calls made to the server are as expected
// given the operations performed
for _, op := range operations {
if err := op.runOp(); err != nil {
t.Errorf("%s: %v", op.desc, err)
}
u, method := <-gotURL, <-gotMethod
tritone marked this conversation as resolved.
Show resolved Hide resolved
if u != op.wantURL {
t.Errorf("%s: unexpected request URL\ngot %q\nwant %q",
op.desc, u, op.wantURL)
}
if method != op.wantMethod {
t.Errorf("%s: unexpected request method\ngot %q\nwant %q",
op.desc, method, op.wantMethod)
}
}

// Check that the client fields have not changed
if c.raw.BasePath != originalRawBasePath {
t.Errorf("raw.BasePath changed\n\tgot:\t\t%v\n\toriginal:\t%v", c.raw.BasePath, originalRawBasePath)
t.Errorf("raw.BasePath changed\n\tgot:\t\t%v\n\toriginal:\t%v",
c.raw.BasePath, originalRawBasePath)
}
if c.readHost != originalReadHost {
t.Errorf("readHost changed\n\tgot:\t\t%v\n\toriginal:\t%v", c.readHost, originalReadHost)
t.Errorf("readHost changed\n\tgot:\t\t%v\n\toriginal:\t%v",
c.readHost, originalReadHost)
}
if c.scheme != originalScheme {
t.Errorf("scheme changed\n\tgot:\t\t%v\n\toriginal:\t%v", c.scheme, originalScheme)
t.Errorf("scheme changed\n\tgot:\t\t%v\n\toriginal:\t%v",
c.scheme, originalScheme)
}
})
}
}

func newTestServerAt(handler func(w http.ResponseWriter, r *http.Request)) (string, *http.Client, func()) {
ts := httptest.NewTLSServer(http.HandlerFunc(handler))
address := ts.Listener.Addr().String()
tlsConf := &tls.Config{InsecureSkipVerify: true}
tr := &http.Transport{
TLSClientConfig: tlsConf,
DialTLS: func(netw, addr string) (net.Conn, error) {
return tls.Dial("tcp", address, tlsConf)
},
}
return address, &http.Client{Transport: tr}, func() {
tr.CloseIdleConnections()
ts.Close()
}
}