From a90f565e47a359464d2c728df03f6ea8f4d0fbba Mon Sep 17 00:00:00 2001 From: Christopher Scott Date: Sat, 20 Mar 2021 17:54:28 -0500 Subject: [PATCH 01/18] testFramework initial implementation with aztables tests --- sdk/internal/go.mod | 8 +- sdk/internal/go.sum | 28 + sdk/internal/testframework/recording.go | 368 ++++++++++++ .../testframework/recording_sanitizer.go | 64 +++ .../testframework/recording_sanitizer_test.go | 144 +++++ sdk/internal/testframework/recording_test.go | 263 +++++++++ sdk/internal/testframework/request_matcher.go | 110 ++++ .../testframework/request_matcher_test.go | 209 +++++++ sdk/tables/aztables/CHANGELOG.md | 2 +- sdk/tables/aztables/go.mod | 2 + sdk/tables/aztables/go.sum | 13 +- .../TestAddEntity-variables.yaml | 5 + .../TestAddEntity.yaml | 121 ++++ .../TestCreateTable-variables.yaml | 5 + .../TestCreateTable.yaml | 75 +++ .../TestQuerySimpleEntity-variables.yaml | 5 + .../TestQuerySimpleEntity.yaml | 342 +++++++++++ .../TestServiceErrors-variables.yaml | 5 + .../TestServiceErrors.yaml | 113 ++++ .../TestAddEntity-variables.yaml | 5 + .../TestAddEntity.yaml | 139 +++++ .../TestCreateTable-variables.yaml | 5 + .../TestCreateTable.yaml | 85 +++ .../TestQuerySimpleEntity-variables.yaml | 5 + .../TestQuerySimpleEntity.yaml | 398 +++++++++++++ .../TestServiceErrors-variables.yaml | 5 + .../TestServiceErrors.yaml | 129 +++++ .../TestCreateTable-variables.yaml | 5 + .../TestCreateTable.yaml | 75 +++ .../TestQueryTable-variables.yaml | 5 + .../TestQueryTable.yaml | 499 ++++++++++++++++ .../TestServiceErrors-variables.yaml | 5 + .../TestServiceErrors.yaml | 113 ++++ .../TestCreateTable-variables.yaml | 5 + .../TestCreateTable.yaml | 85 +++ .../TestQueryTable-variables.yaml | 5 + .../TestQueryTable.yaml | 532 ++++++++++++++++++ .../TestServiceErrors-variables.yaml | 5 + .../TestServiceErrors.yaml | 129 +++++ sdk/tables/aztables/tableClient.go | 50 +- sdk/tables/aztables/tableClient_test.go | 112 +++- sdk/tables/aztables/tableServiceClient.go | 62 ++ .../aztables/tableServiceClient_test.go | 104 ++++ sdk/tables/aztables/zc_client_options.go | 6 +- sdk/tables/aztables/zc_tableConstants.go | 22 + sdk/tables/aztables/zc_table_pagers.go | 127 +++++ sdk/tables/aztables/zt_tableRecordedTests.go | 132 +++++ sdk/tables/aztables/zt_test.go | 2 +- .../aztables/zz_generated_connection.go | 4 +- 49 files changed, 4705 insertions(+), 32 deletions(-) create mode 100644 sdk/internal/testframework/recording.go create mode 100644 sdk/internal/testframework/recording_sanitizer.go create mode 100644 sdk/internal/testframework/recording_sanitizer_test.go create mode 100644 sdk/internal/testframework/recording_test.go create mode 100644 sdk/internal/testframework/request_matcher.go create mode 100644 sdk/internal/testframework/request_matcher_test.go create mode 100644 sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestAddEntity-variables.yaml create mode 100644 sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestAddEntity.yaml create mode 100644 sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestCreateTable-variables.yaml create mode 100644 sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestCreateTable.yaml create mode 100644 sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestQuerySimpleEntity-variables.yaml create mode 100644 sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestQuerySimpleEntity.yaml create mode 100644 sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestServiceErrors-variables.yaml create mode 100644 sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestServiceErrors.yaml create mode 100644 sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestAddEntity-variables.yaml create mode 100644 sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestAddEntity.yaml create mode 100644 sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestCreateTable-variables.yaml create mode 100644 sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestCreateTable.yaml create mode 100644 sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestQuerySimpleEntity-variables.yaml create mode 100644 sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestQuerySimpleEntity.yaml create mode 100644 sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestServiceErrors-variables.yaml create mode 100644 sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestServiceErrors.yaml create mode 100644 sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestCreateTable-variables.yaml create mode 100644 sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestCreateTable.yaml create mode 100644 sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestQueryTable-variables.yaml create mode 100644 sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestQueryTable.yaml create mode 100644 sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestServiceErrors-variables.yaml create mode 100644 sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestServiceErrors.yaml create mode 100644 sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestCreateTable-variables.yaml create mode 100644 sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestCreateTable.yaml create mode 100644 sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestQueryTable-variables.yaml create mode 100644 sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestQueryTable.yaml create mode 100644 sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestServiceErrors-variables.yaml create mode 100644 sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestServiceErrors.yaml create mode 100644 sdk/tables/aztables/tableServiceClient.go create mode 100644 sdk/tables/aztables/tableServiceClient_test.go create mode 100644 sdk/tables/aztables/zc_tableConstants.go create mode 100644 sdk/tables/aztables/zc_table_pagers.go create mode 100644 sdk/tables/aztables/zt_tableRecordedTests.go diff --git a/sdk/internal/go.mod b/sdk/internal/go.mod index 8c500ce1c435..55f016992352 100644 --- a/sdk/internal/go.mod +++ b/sdk/internal/go.mod @@ -2,4 +2,10 @@ module github.com/Azure/azure-sdk-for-go/sdk/internal go 1.14 -require golang.org/x/net v0.0.0-20201010224723-4f7140c49acb +require ( + github.com/Azure/azure-sdk-for-go/sdk/azcore v0.14.2 // indirect + github.com/dnaeon/go-vcr v1.1.0 + golang.org/x/net v0.0.0-20201010224723-4f7140c49acb + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c + gopkg.in/yaml.v2 v2.4.0 +) diff --git a/sdk/internal/go.sum b/sdk/internal/go.sum index c59642cdfa12..cadb7b65ee19 100644 --- a/sdk/internal/go.sum +++ b/sdk/internal/go.sum @@ -1,12 +1,40 @@ +github.com/Azure/azure-sdk-for-go/sdk/azcore v0.14.2 h1:jBp1eg+iY1S6SEjISakVfHmvDxfj8bg1Mw9JFwpCKag= +github.com/Azure/azure-sdk-for-go/sdk/azcore v0.14.2/go.mod h1:pElNP+u99BvCZD+0jOlhI9OC/NB2IDTOTGZOZH0Qhq8= +github.com/Azure/azure-sdk-for-go/sdk/internal v0.5.0/go.mod h1:k4KbFSunV/+0hOHL1vyFaPsiYQ1Vmvy1TBpmtvCDLZM= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/dnaeon/go-vcr v1.1.0 h1:ReYa/UBrRyQdant9B4fNHGoCNKw6qh6P0fsdGmZpR7c= +github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20201010224723-4f7140c49acb h1:mUVeFHoDKis5nxCAzoAi7E8Ghb86EXh/RK6wtvJIqRY= golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c h1:KHUzaHIpjWVlVVNh65G3hhuj3KB1HnjY6Cq5cTvRQT8= +golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/sdk/internal/testframework/recording.go b/sdk/internal/testframework/recording.go new file mode 100644 index 000000000000..bb53ed1796b7 --- /dev/null +++ b/sdk/internal/testframework/recording.go @@ -0,0 +1,368 @@ +// +build go1.13 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package testframework + +import ( + "fmt" + "io/ioutil" + "math/rand" + "net/http" + "os" + "path/filepath" + "strconv" + "strings" + "time" + + "github.com/dnaeon/go-vcr/cassette" + "github.com/dnaeon/go-vcr/recorder" + + chk "gopkg.in/check.v1" + "gopkg.in/yaml.v2" +) + +type Recording struct { + SessionName string + RecordingFile string + VariablesFile string + Mode RecordMode + variables map[string]string `yaml:"variables"` + previousSessionVariables map[string]string `yaml:"variables"` + recorder *recorder.Recorder + src rand.Source + sanitizer *RecordingSanitizer + c *chk.C +} + +const ( + alphanumericBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" + alphanumericLowercaseBytes = "abcdefghijklmnopqrstuvwxyz1234567890" + randomSeedVariableName = "randomSeed" + ModeEnvironmentVariableName = "AZURE_TEST_MODE" +) + +// Inspired by https://stackoverflow.com/questions/22892120/how-to-generate-a-random-string-of-a-fixed-length-in-go +const ( + letterIdxBits = 6 // 6 bits to represent a letter index + letterIdxMask = 1< 0 { + // Save the variables after merging them + + //TODO: Merge values from previousVariables that are not in variables to variables + + // Marshal to YAML and save variables + data, err := yaml.Marshal(r.variables) + if err != nil { + return err + } + + f, err := r.createVariablesFileIfNotExists() + if err != nil { + return err + } + + defer f.Close() + + // http://www.yaml.org/spec/1.2/spec.html#id2760395 + _, err = f.Write([]byte("---\n")) + if err != nil { + return err + } + + _, err = f.Write(data) + if err != nil { + return err + } + } + return nil +} + +// Gets an environment variable by name and panics if it is not found +func GetRequiredEnv(name string) string { + env, ok := os.LookupEnv(name) + if ok { + return env + } else { + panic(envNotExistsError(name)) + } +} + +// gets an environment variable by name and returns the defaultValue if not found +func GetOptionalEnv(name string, defaultValue string) string { + env, ok := os.LookupEnv(name) + if ok { + return env + } else { + return defaultValue + } +} + +// generate a recorded random alpha numeric id +// if the recording has a randomSeed already set, the value will be generated from that seed, else a new random seed will be used +func (r *Recording) GenerateAlphaNumericId(prefix string, length int, lowercaseOnly bool) string { + + if length <= len(prefix) { + panic("length must be greater than prefix") + } + + r.initRandomSource() + + sb := strings.Builder{} + sb.Grow(length) + sb.WriteString(prefix) + i := length - len(prefix) - 1 + // A src.Int63() generates 63 random bits, enough for letterIdxMax characters! + for cache, remain := r.src.Int63(), letterIdxMax; i >= 0; { + if remain == 0 { + cache, remain = r.src.Int63(), letterIdxMax + } + if lowercaseOnly { + if idx := int(cache & letterIdxMask); idx < len(alphanumericLowercaseBytes) { + sb.WriteByte(alphanumericLowercaseBytes[idx]) + i-- + } + } else { + if idx := int(cache & letterIdxMask); idx < len(alphanumericBytes) { + sb.WriteByte(alphanumericBytes[idx]) + i-- + } + } + cache >>= letterIdxBits + remain-- + } + + return sb.String() +} + +func (r *Recording) matchRequest(req *http.Request, rec cassette.Request) bool { + isMatch := compareMethods(req, rec, r.c) && + compareURLs(req, rec, r.c) && + compareHeaders(req, rec, r.c) && + compareBodies(req, rec, r.c) + + return isMatch +} + +func missingRequestError(req *http.Request) string { + reqUrl := req.URL.String() + return fmt.Sprintf("\nNo matching recorded request found.\nRequest: [%s] %s\n", req.Method, reqUrl) +} + +func envNotExistsError(varName string) string { + return "Required environment variable not set: " + varName +} + +// Applies the VariableType transform to the value +// If variableType is not provided or Default, return result +// If variableType is Secret_String, return SanitizedValue +// If variableType isSecret_Base64String return SanitizedBase64Value +func applyVariableOptions(val *string, variableType ...VariableType) string { + + switch len(variableType) { + case 0: + return *val + default: + switch vt := variableType[0]; vt { + case Secret_String: + return SanitizedValue + case Secret_Base64String: + return SanitizedBase64Value + default: + return *val + } + } +} + +// Initializes the Source to be used for random value creation in this Recording +func (r *Recording) initRandomSource() { + // if we already have a Source generated, return immediately + if r.src != nil { + return + } + + var seed int64 + var err error + + // check to see if we already have a random seed stored, use that if so + seedString, ok := r.previousSessionVariables[randomSeedVariableName] + if ok { + seed, err = strconv.ParseInt(seedString, 10, 64) + } + + // We did not have a random seed already stored; create a new one + if !ok || err != nil || r.Mode == Live { + seed = time.Now().Unix() + r.variables[randomSeedVariableName] = strconv.FormatInt(seed, 10) + } + + // create a Source with the seed + r.src = rand.NewSource(seed) +} + +// returns (recordingFilePath, variablesFilePath) +func getFilePaths(c *chk.C, suffixes []string) (string, string) { + testName := strings.Split(c.TestName(), ".") + var suffix string = "" + if len(suffixes) > 0 { + suffix = "(" + strings.Join(suffixes, ",") + ")" + } + recPath := "recordings/" + testName[0] + suffix + "/" + testName[1] + varPath := fmt.Sprintf("%s-variables.yaml", recPath) + return recPath, varPath +} + +// Calls os.Create on the VariablesFile and creates it if it or the path does not exist +// Callers must call Close on the result +func (r *Recording) createVariablesFileIfNotExists() (*os.File, error) { + f, err := os.Create(r.VariablesFile) + if err != nil { + // Create directory for the variables if missing + variablesDir := filepath.Dir(r.VariablesFile) + if _, err := os.Stat(variablesDir); os.IsNotExist(err) { + if err = os.MkdirAll(variablesDir, 0755); err != nil { + return nil, err + } + } + + f, err = os.Create(r.VariablesFile) + if err != nil { + return nil, err + } + } + + return f, nil +} + +func (r *Recording) unmarshalVariablesFile(out interface{}) error { + data, err := ioutil.ReadFile(r.VariablesFile) + if err != nil { + // If the file or dir do not exist, this is not an error to report + if os.IsNotExist(err) { + return nil + } else { + return err + } + } else { + err = yaml.Unmarshal(data, out) + } + return nil +} + +func (r *Recording) initVariables() error { + err := r.unmarshalVariablesFile(r.previousSessionVariables) + if err != nil { + return nil + } + + return nil +} + +var modeMap = map[RecordMode]recorder.Mode{ + Record: recorder.ModeRecording, + Live: recorder.ModeDisabled, + Playback: recorder.ModeReplaying, +} diff --git a/sdk/internal/testframework/recording_sanitizer.go b/sdk/internal/testframework/recording_sanitizer.go new file mode 100644 index 000000000000..9064da86c6f3 --- /dev/null +++ b/sdk/internal/testframework/recording_sanitizer.go @@ -0,0 +1,64 @@ +// +build go1.13 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package testframework + +import ( + "github.com/dnaeon/go-vcr/cassette" + "github.com/dnaeon/go-vcr/recorder" + "net/http" +) + +type RecordingSanitizer struct { + recorder *recorder.Recorder + headersToSanitize map[string]*string + urlSanitizer StringSanitizer +} + +type StringSanitizer func(*string) error + +const SanitizedValue string = "sanitized" +const SanitizedBase64Value string = "Kg==" + +var sanitizedValueSlice = []string{SanitizedValue} + +func DefaultSanitizer(recorder *recorder.Recorder) *RecordingSanitizer { + // The default sanitizer sanitizes the Authorization header + s := &RecordingSanitizer{headersToSanitize: map[string]*string{"Authorization": nil}, recorder: recorder, urlSanitizer: DefaultStringSanitizer} + recorder.AddSaveFilter(s.applySaveFilter) + + return s +} + +func (s *RecordingSanitizer) AddSanitizedHeaders(headers ...string) { + for _, headerName := range headers { + s.headersToSanitize[headerName] = nil + } +} + +func (s *RecordingSanitizer) sanitizeHeaders(header http.Header) { + for headerName := range s.headersToSanitize { + if _, ok := header[headerName]; ok { + header[headerName] = sanitizedValueSlice + } + } +} + +func (s *RecordingSanitizer) AddUrlSanitizer(sanitizer StringSanitizer) { + s.urlSanitizer = sanitizer +} + +func (s *RecordingSanitizer) sanitizeURL(url *string) error { + return s.urlSanitizer(url) +} + +func (s *RecordingSanitizer) applySaveFilter(i *cassette.Interaction) error { + s.sanitizeHeaders(i.Request.Headers) + return s.sanitizeURL(&i.Request.URL) +} + +func DefaultStringSanitizer(s *string) error { + return nil +} diff --git a/sdk/internal/testframework/recording_sanitizer_test.go b/sdk/internal/testframework/recording_sanitizer_test.go new file mode 100644 index 000000000000..4fadba6c3bda --- /dev/null +++ b/sdk/internal/testframework/recording_sanitizer_test.go @@ -0,0 +1,144 @@ +// +build go1.13 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package testframework + +import ( + "net/http" + "os" + "strings" + "testing" + + "github.com/Azure/azure-sdk-for-go/sdk/internal/mock" + "github.com/dnaeon/go-vcr/cassette" + "github.com/dnaeon/go-vcr/recorder" + chk "gopkg.in/check.v1" +) + +type recordingSanitizerTests struct{} + +// Hookup to the testing framework +func Test(t *testing.T) { chk.TestingT(t) } + +var _ = chk.Suite(&recordingSanitizerTests{}) + +const authHeader string = "Authorization" +const customHeader1 string = "Fooheader" +const customHeader2 string = "Barheader" +const nonSanitizedHeader string = "notsanitized" + +func (s *recordingSanitizerTests) TestDefaultSanitizerSanitizesAuthHeader(c *chk.C) { + server, cleanup := mock.NewServer() + server.SetResponse() + defer cleanup() + rt := NewMockRoundTripper(server) + r, _ := recorder.NewAsMode(getTestFileName(c, false), recorder.ModeRecording, rt) + + DefaultSanitizer(r) + + req, _ := http.NewRequest(http.MethodPost, server.URL(), nil) + req.Header.Add(authHeader, "superSecret") + + r.RoundTrip(req) + r.Stop() + + c.Assert(req.Header.Get(authHeader), chk.Equals, SanitizedValue) + + rec, err := cassette.Load(getTestFileName(c, false)) + c.Assert(err, chk.IsNil) + + for _, i := range rec.Interactions { + c.Assert(i.Request.Headers.Get(authHeader), chk.Equals, SanitizedValue) + } +} + +func (s *recordingSanitizerTests) TestAddSanitizedHeadersSanitizes(c *chk.C) { + server, cleanup := mock.NewServer() + server.SetResponse() + defer cleanup() + rt := NewMockRoundTripper(server) + r, _ := recorder.NewAsMode(getTestFileName(c, false), recorder.ModeRecording, rt) + + target := DefaultSanitizer(r) + target.AddSanitizedHeaders(customHeader1, customHeader2) + + req, _ := http.NewRequest(http.MethodPost, server.URL(), nil) + req.Header.Add(customHeader1, "superSecret") + req.Header.Add(customHeader2, "verySecret") + safeValue := "safeValue" + req.Header.Add(nonSanitizedHeader, safeValue) + + r.RoundTrip(req) + r.Stop() + + c.Assert(req.Header.Get(customHeader1), chk.Equals, SanitizedValue) + c.Assert(req.Header.Get(customHeader2), chk.Equals, SanitizedValue) + c.Assert(req.Header.Get(nonSanitizedHeader), chk.Equals, safeValue) + + rec, err := cassette.Load(getTestFileName(c, false)) + c.Assert(err, chk.IsNil) + + for _, i := range rec.Interactions { + c.Assert(i.Request.Headers.Get(customHeader1), chk.Equals, SanitizedValue) + c.Assert(i.Request.Headers.Get(customHeader2), chk.Equals, SanitizedValue) + c.Assert(i.Request.Headers.Get(nonSanitizedHeader), chk.Equals, safeValue) + } +} + +func (s *recordingSanitizerTests) TestAddUrlSanitizerSanitizes(c *chk.C) { + server, cleanup := mock.NewServer() + server.SetResponse(mock.WithStatusCode(http.StatusNoContent)) + defer cleanup() + rt := NewMockRoundTripper(server) + r, _ := recorder.NewAsMode(getTestFileName(c, false), recorder.ModeRecording, rt) + + sanitizedUrl := server.URL() + secret := "/secretvalue" + + target := DefaultSanitizer(r) + target.AddUrlSanitizer(func(url *string) error { + *url = strings.Replace(*url, secret, "", -1) + return nil + }) + + req, _ := http.NewRequest(http.MethodPost, sanitizedUrl+secret, nil) + + r.RoundTrip(req) + r.Stop() + + rec, err := cassette.Load(getTestFileName(c, false)) + c.Assert(err, chk.IsNil) + + for _, i := range rec.Interactions { + c.Assert(i.Request.URL, chk.Not(chk.Equals), sanitizedUrl+secret) + c.Assert(i.Request.URL, chk.Equals, sanitizedUrl) + } +} + +func (s *recordingSanitizerTests) TearDownSuite(c *chk.C) { + // cleanup test files + err := os.RemoveAll("testfiles") + c.Log(err) +} + +func getTestFileName(c *chk.C, addSuffix bool) string { + name := "testfiles/" + c.TestName() + if addSuffix { + name = name + ".yaml" + } + return name +} + +type mockRoundTripper struct { + server *mock.Server +} + +func NewMockRoundTripper(server *mock.Server) *mockRoundTripper { + return &mockRoundTripper{server: server} +} + +func (m *mockRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { + return m.server.Do(req) +} diff --git a/sdk/internal/testframework/recording_test.go b/sdk/internal/testframework/recording_test.go new file mode 100644 index 000000000000..507024c27d45 --- /dev/null +++ b/sdk/internal/testframework/recording_test.go @@ -0,0 +1,263 @@ +// +build go1.13 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package testframework + +import ( + "io/ioutil" + "net/http" + "os" + "strings" + + "github.com/Azure/azure-sdk-for-go/sdk/internal/mock" + "github.com/dnaeon/go-vcr/cassette" + + chk "gopkg.in/check.v1" +) + +type recordingTests struct{} + +var _ = chk.Suite(&recordingTests{}) + +func (r *recordingTests) Test_InitializeRecording(c *chk.C) { + + expectedMode := Playback + + target, err := NewRecording(c, expectedMode) + c.Assert(err, chk.IsNil) + c.Assert(target.RecordingFile, chk.NotNil) + c.Assert(target.VariablesFile, chk.NotNil) + c.Assert(target.Mode, chk.Equals, expectedMode) + + err = target.Stop() + c.Assert(err, chk.IsNil) +} + +func (r *recordingTests) Test_StopDoesNotSaveVariablesWhenNoVariablesExist(c *chk.C) { + + target, err := NewRecording(c, Playback) + c.Assert(err, chk.IsNil) + + err = target.Stop() + c.Assert(err, chk.IsNil) + + _, err = ioutil.ReadFile(target.VariablesFile) + c.Assert(os.IsNotExist(err), chk.Equals, true) +} + +func (r *recordingTests) Test_RecordedVariables(c *chk.C) { + + nonExistingEnvVar := "nonExistingEnvVar" + expectedVariableValue := "foobar" + variablesMap := map[string]string{} + + target, err := NewRecording(c, Playback) + c.Assert(err, chk.IsNil) + + // optional variables always succeed. + c.Assert(target.GetOptionalRecordedVariable(nonExistingEnvVar, expectedVariableValue), chk.Equals, expectedVariableValue) + + // non existent variables panic + c.Assert(func() { target.GetRecordedVariable(nonExistingEnvVar) }, chk.Panics, envNotExistsError(nonExistingEnvVar)) + + // now create the env variable and check that it can be fetched + os.Setenv(nonExistingEnvVar, expectedVariableValue) + defer os.Unsetenv(nonExistingEnvVar) + c.Assert(target.GetRecordedVariable(nonExistingEnvVar), chk.Equals, expectedVariableValue) + + err = target.Stop() + c.Assert(err, chk.IsNil) + + // check that a variables file was created with the correct variable + target.unmarshalVariablesFile(variablesMap) + actualValue, ok := variablesMap[nonExistingEnvVar] + c.Assert(ok, chk.Equals, true) + c.Assert(actualValue, chk.Equals, expectedVariableValue) +} + +func (r *recordingTests) Test_RecordedVariablesSanitized(c *chk.C) { + + SanitizedStringVar := "sanitizedvar" + SanitizedBase64StrigVar := "sanitizedbase64var" + secret := "secretstring" + secretBase64 := "asdfasdf==" + variablesMap := map[string]string{} + + target, err := NewRecording(c, Playback) + c.Assert(err, chk.IsNil) + + // call GetOptionalRecordedVariable with the Secret_String VariableType arg + c.Assert(target.GetOptionalRecordedVariable(SanitizedStringVar, secret, Secret_String), chk.Equals, secret) + + // call GetOptionalRecordedVariable with the Secret_Base64String VariableType arg + c.Assert(target.GetOptionalRecordedVariable(SanitizedBase64StrigVar, secretBase64, Secret_Base64String), chk.Equals, secretBase64) + + // Calling Stop will save the variables and apply the sanitization options + err = target.Stop() + c.Assert(err, chk.IsNil) + + // check that a variables file was created with the correct variables + target.unmarshalVariablesFile(variablesMap) + actualValue, ok := variablesMap[SanitizedStringVar] + c.Assert(ok, chk.Equals, true) + // the saved value is sanitized + c.Assert(actualValue, chk.Equals, SanitizedValue) + + target.unmarshalVariablesFile(variablesMap) + actualValue, ok = variablesMap[SanitizedBase64StrigVar] + c.Assert(ok, chk.Equals, true) + // the saved value is sanitized + c.Assert(actualValue, chk.Equals, SanitizedBase64Value) +} + +func (r *recordingTests) Test_StopSavesVariablesIfExistAndReadsPreviousVariables(c *chk.C) { + + expectedVariableName := "someVariable" + expectedVariableValue := "foobar" + variablesMap := map[string]string{} + + target, err := NewRecording(c, Playback) + c.Assert(err, chk.IsNil) + + target.GetOptionalRecordedVariable(expectedVariableName, expectedVariableValue) + + err = target.Stop() + c.Assert(err, chk.IsNil) + + // check that a variables file was created with the correct variable + target.unmarshalVariablesFile(variablesMap) + actualValue, ok := variablesMap[expectedVariableName] + c.Assert(ok, chk.Equals, true) + c.Assert(actualValue, chk.Equals, expectedVariableValue) + + variablesMap = map[string]string{} + target2, err := NewRecording(c, Playback) + c.Assert(err, chk.IsNil) + + err = target.Stop() + c.Assert(err, chk.IsNil) + + // check that a variables file was created with the variables loaded from the previous recording + target2.unmarshalVariablesFile(variablesMap) + actualValue, ok = variablesMap[expectedVariableName] + c.Assert(ok, chk.Equals, true) + c.Assert(actualValue, chk.Equals, expectedVariableValue) +} + +func (r *recordingTests) Test_GenerateAlphaNumericId(c *chk.C) { + + prefix := "myprefix" + + target, err := NewRecording(c, Playback) + c.Assert(err, chk.IsNil) + + generated1 := target.GenerateAlphaNumericId(prefix, 10, true) + + c.Assert(len(generated1), chk.Equals, 10) + c.Assert(strings.HasPrefix(generated1, prefix), chk.Equals, true) + + generated1a := target.GenerateAlphaNumericId(prefix, 10, true) + c.Assert(generated1a, chk.Not(chk.Equals), generated1) + + err = target.Stop() + c.Assert(err, chk.IsNil) + + target2, err := NewRecording(c, Playback) + c.Assert(err, chk.IsNil) + + generated2 := target2.GenerateAlphaNumericId(prefix, 10, true) + + // The two generated Ids should be the same since target2 loaded the saved random seed from target + c.Assert(generated1, chk.Equals, generated2) + + err = target.Stop() + c.Assert(err, chk.IsNil) +} + +func (s *recordingTests) TestRecordRequestsAndDoMatching(c *chk.C) { + server, cleanup := mock.NewServer() + server.SetResponse() + defer cleanup() + rt := NewMockRoundTripper(server) + + target, err := NewRecording(c, Playback) + target.recorder.SetTransport(rt) + + reqUrl := server.URL() + "/" + target.GenerateAlphaNumericId("", 5, true) + + req, _ := http.NewRequest(http.MethodPost, reqUrl, nil) + + // record the request + target.Do(req) + err = target.Stop() + c.Assert(err, chk.IsNil) + + rec, err := cassette.Load(target.SessionName) + c.Assert(err, chk.IsNil) + + for _, i := range rec.Interactions { + c.Assert(i.Request.URL, chk.Equals, reqUrl) + } + + // re-initialize the recording + target, err = NewRecording(c, Playback) + target.recorder.SetTransport(rt) + + // re-create the random url using the recorded variables + reqUrl = server.URL() + "/" + target.GenerateAlphaNumericId("", 5, true) + req, _ = http.NewRequest(http.MethodPost, reqUrl, nil) + + // playback the request + target.Do(req) + err = target.Stop() + c.Assert(err, chk.IsNil) +} + +func (s *recordingTests) TestRecordRequestsAndFailMatchingForMissingRecording(c *chk.C) { + server, cleanup := mock.NewServer() + server.SetResponse() + defer cleanup() + rt := NewMockRoundTripper(server) + + target, err := NewRecording(c, Playback) + target.recorder.SetTransport(rt) + + reqUrl := server.URL() + "/" + target.GenerateAlphaNumericId("", 5, true) + + req, _ := http.NewRequest(http.MethodPost, reqUrl, nil) + + // record the request + target.Do(req) + err = target.Stop() + c.Assert(err, chk.IsNil) + + rec, err := cassette.Load(target.SessionName) + c.Assert(err, chk.IsNil) + + for _, i := range rec.Interactions { + c.Assert(i.Request.URL, chk.Equals, reqUrl) + } + + // re-initialize the recording + target, err = NewRecording(c, Playback) + target.recorder.SetTransport(rt) + + // re-create the random url using the recorded variables + reqUrl = server.URL() + "/" + "mismatchedRequest" + req, _ = http.NewRequest(http.MethodPost, reqUrl, nil) + + // playback the request + c.Assert(func() { target.Do(req) }, chk.Panics, missingRequestError(req)) + c.Succeed() + err = target.Stop() + c.Assert(err, chk.IsNil) +} + +func (r *recordingTests) TearDownSuite(c *chk.C) { + + // cleanup test files + err := os.RemoveAll("recordings") + c.Log(err) +} diff --git a/sdk/internal/testframework/request_matcher.go b/sdk/internal/testframework/request_matcher.go new file mode 100644 index 000000000000..65eee6b68730 --- /dev/null +++ b/sdk/internal/testframework/request_matcher.go @@ -0,0 +1,110 @@ +// +build go1.13 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package testframework + +import ( + "bytes" + "io/ioutil" + "net/http" + "reflect" + + "github.com/dnaeon/go-vcr/cassette" + chk "gopkg.in/check.v1" +) + +type RequestMatcher struct { + ignoredHeaders map[string]*string +} + +var ignoredHeaders = map[string]*string{ + "Date": nil, + "X-Ms-Date": nil, + "x-ms-date": nil, + "x-ms-client-request-id": nil, + "User-Agent": nil, + "Request-Id": nil, + "traceparent": nil, + "Authorization": nil, +} + +var recordingHeaderMissing = "Test recording headers do not match. Header '%s' is present in request but not in recording." +var requestHeaderMissing = "Test recording headers do not match. Header '%s' is present in recording but not in request." +var headerValuesMismatch = "Test recording header '%s' does not match. request: %s, recording: %s" +var methodMismatch = "Test recording methods do not match. request: %s, recording: %s" +var urlMismatch = "Test recording URLs do not match. request: %s, recording: %s" + +func compareBodies(r *http.Request, i cassette.Request, c *chk.C) bool { + body := bytes.Buffer{} + if r.Body != nil { + _, err := body.ReadFrom(r.Body) + if err != nil { + return false + } + r.Body = ioutil.NopCloser(&body) + } + bodiesMatch := body.String() == i.Body + if !bodiesMatch { + c.Logf("Test recording bodies do not match.\nrequest: %s\nrecording: %s", body.String(), i.Body) + } + return bodiesMatch +} + +func compareURLs(r *http.Request, i cassette.Request, c *chk.C) bool { + if r.URL.String() != i.URL { + c.Logf(urlMismatch, r.URL.String(), i.URL) + return false + } + return true +} + +func compareMethods(r *http.Request, i cassette.Request, c *chk.C) bool { + if r.Method != i.Method { + c.Logf(methodMismatch, r.Method, i.Method) + return false + } + return true +} + +func compareHeaders(r *http.Request, i cassette.Request, c *chk.C) bool { + unVisitedCassetteKeys := make(map[string]*string, len(i.Headers)) + // clone the cassette keys to track which we have seen + for k := range i.Headers { + if _, ignore := ignoredHeaders[k]; ignore { + // don't copy ignored headers + continue + } + unVisitedCassetteKeys[k] = nil + } + //iterate through all the request headers to compare them to cassette headers + for key, requestHeader := range r.Header { + if _, ignore := ignoredHeaders[key]; ignore { + // this is an ignorable header + continue + } + delete(unVisitedCassetteKeys, key) + if recordedHeader, foundMatch := i.Headers[key]; foundMatch { + headersMatch := reflect.DeepEqual(requestHeader, recordedHeader) + if !headersMatch { + // headers don't match + c.Logf(headerValuesMismatch, key, requestHeader, recordedHeader) + return false + } + + } else { + // header not found + c.Logf(recordingHeaderMissing, key) + return false + } + } + if len(unVisitedCassetteKeys) > 0 { + // headers exist in the recording that do not exist in the request + for headerName := range unVisitedCassetteKeys { + c.Logf(requestHeaderMissing, headerName) + } + return false + } + return true +} diff --git a/sdk/internal/testframework/request_matcher_test.go b/sdk/internal/testframework/request_matcher_test.go new file mode 100644 index 000000000000..57ebba7eb67c --- /dev/null +++ b/sdk/internal/testframework/request_matcher_test.go @@ -0,0 +1,209 @@ +// +build go1.13 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package testframework + +import ( + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "strings" + + "github.com/Azure/azure-sdk-for-go/sdk/internal/uuid" + "github.com/dnaeon/go-vcr/cassette" + + chk "gopkg.in/check.v1" +) + +type requestMatcherTests struct{} + +const matchedBody string = "Matching body." +const unMatchedBody string = "This body does not match." + +// Hookup to the testing framework +var _ = chk.Suite(&requestMatcherTests{}) + +func (s *requestMatcherTests) TestCompareBodies(c *chk.C) { + + req := http.Request{Body: closerFromString(matchedBody)} + recReq := cassette.Request{Body: matchedBody} + + isMatch := compareBodies(&req, recReq, c) + + c.Assert(isMatch, chk.Equals, true) + + // make the requests mis-match + req.Body = closerFromString((unMatchedBody)) + + isMatch = compareBodies(&req, recReq, c) + + c.Assert(isMatch, chk.Equals, false) + log := c.GetTestLog() + c.Assert(strings.HasPrefix(log, "Test recording bodies do not match"), chk.Equals, true) +} + +func (s *requestMatcherTests) TestCompareHeadersIgnoresIgnoredHeaders(c *chk.C) { + + // populate only ignored headers that do not match + reqHeaders := make(http.Header) + recordedHeaders := make(http.Header) + for headerName := range ignoredHeaders { + reqHeaders[headerName] = []string{uuid.New().String()} + recordedHeaders[headerName] = []string{uuid.New().String()} + } + + req := http.Request{Header: reqHeaders} + recReq := cassette.Request{Headers: recordedHeaders} + + isMatch := compareHeaders(&req, recReq, c) + + // All headers match + c.Assert(isMatch, chk.Equals, true) +} + +func (s *requestMatcherTests) TestCompareHeadersMatchesHeaders(c *chk.C) { + + // populate only ignored headers that do not match + reqHeaders := make(http.Header) + recordedHeaders := make(http.Header) + header1 := "header1" + headerValue := []string{"some value"} + + reqHeaders[header1] = headerValue + recordedHeaders[header1] = headerValue + + req := http.Request{Header: reqHeaders} + recReq := cassette.Request{Headers: recordedHeaders} + + c.Assert( + compareHeaders(&req, recReq, c), + chk.Equals, + true) +} + +func (s *requestMatcherTests) TestCompareHeadersFailsMissingRecHeader(c *chk.C) { + + // populate only ignored headers that do not match + reqHeaders := make(http.Header) + recordedHeaders := make(http.Header) + header1 := "header1" + header2 := "header2" + headerValue := []string{"some value"} + + reqHeaders[header1] = headerValue + recordedHeaders[header1] = headerValue + + req := http.Request{Header: reqHeaders} + recReq := cassette.Request{Headers: recordedHeaders} + + // add a new header to the just req + reqHeaders[header2] = headerValue + + c.Assert( + compareHeaders(&req, recReq, c), + chk.Equals, + false) + c.Assert(c.GetTestLog(), chk.Equals, fmt.Sprintf(recordingHeaderMissing+"\n", header2)) +} + +func (s *requestMatcherTests) TestCompareHeadersFailsMissingReqHeader(c *chk.C) { + + // populate only ignored headers that do not match + reqHeaders := make(http.Header) + recordedHeaders := make(http.Header) + header1 := "header1" + header2 := "header2" + headerValue := []string{"some value"} + + reqHeaders[header1] = headerValue + recordedHeaders[header1] = headerValue + + req := http.Request{Header: reqHeaders} + recReq := cassette.Request{Headers: recordedHeaders} + + // add a new header to just the recording + recordedHeaders[header2] = headerValue + + c.Assert( + compareHeaders(&req, recReq, c), + chk.Equals, + false) + c.Assert(c.GetTestLog(), chk.Equals, fmt.Sprintf(requestHeaderMissing+"\n", header2)) +} + +func (s *requestMatcherTests) TestCompareHeadersFailsMismatchedValues(c *chk.C) { + + // populate only ignored headers that do not match + reqHeaders := make(http.Header) + recordedHeaders := make(http.Header) + header1 := "header1" + header2 := "header2" + headerValue := []string{"some value"} + mismatch := []string{"mismatch"} + + reqHeaders[header1] = headerValue + recordedHeaders[header1] = headerValue + + req := http.Request{Header: reqHeaders} + recReq := cassette.Request{Headers: recordedHeaders} + + // header names match but values are different + recordedHeaders[header2] = headerValue + reqHeaders[header2] = mismatch + + c.Assert( + compareHeaders(&req, recReq, c), + chk.Equals, + false) + c.Assert(c.GetTestLog(), chk.Equals, fmt.Sprintf(headerValuesMismatch+"\n", header2, mismatch, headerValue)) +} + +func (s *requestMatcherTests) TestCompareURLs(c *chk.C) { + scheme := "https" + host := "foo.bar" + req := http.Request{URL: &url.URL{Scheme: scheme, Host: host}} + recReq := cassette.Request{URL: scheme + "://" + host} + + c.Assert( + compareURLs(&req, recReq, c), + chk.Equals, + true) + + req.URL.Path = "noMatch" + + c.Assert( + compareURLs(&req, recReq, c), + chk.Equals, + false) + + c.Assert(c.GetTestLog(), chk.Equals, fmt.Sprintf(urlMismatch+"\n", req.URL.String(), recReq.URL)) +} + +func (s *requestMatcherTests) TestCompareMethods(c *chk.C) { + methodPost := "POST" + methodPatch := "PATCH" + req := http.Request{Method: methodPost} + recReq := cassette.Request{Method: methodPost} + + c.Assert( + compareMethods(&req, recReq, c), + chk.Equals, + true) + + req.Method = methodPatch + + c.Assert( + compareMethods(&req, recReq, c), + chk.Equals, + false) + + c.Assert(c.GetTestLog(), chk.Equals, fmt.Sprintf(methodMismatch+"\n", req.Method, recReq.Method)) +} + +func closerFromString(content string) io.ReadCloser { + return ioutil.NopCloser(strings.NewReader(content)) +} diff --git a/sdk/tables/aztables/CHANGELOG.md b/sdk/tables/aztables/CHANGELOG.md index b8c2e452d173..79cb7d0abef2 100644 --- a/sdk/tables/aztables/CHANGELOG.md +++ b/sdk/tables/aztables/CHANGELOG.md @@ -1,3 +1,3 @@ # Release History -## v0.1.0 (Unreleased) +## 0.1.0 (Unreleased) \ No newline at end of file diff --git a/sdk/tables/aztables/go.mod b/sdk/tables/aztables/go.mod index a37066df4bb0..c557e375933e 100644 --- a/sdk/tables/aztables/go.mod +++ b/sdk/tables/aztables/go.mod @@ -2,6 +2,8 @@ module github.com/Azure/azure-sdk-for-go/sdk/tables/aztables go 1.13 +replace github.com/Azure/azure-sdk-for-go/sdk/internal => ../../internal + require ( github.com/Azure/azure-sdk-for-go/sdk/azcore v0.14.1 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c diff --git a/sdk/tables/aztables/go.sum b/sdk/tables/aztables/go.sum index 369497e547f8..bba755a4acb4 100644 --- a/sdk/tables/aztables/go.sum +++ b/sdk/tables/aztables/go.sum @@ -1,12 +1,13 @@ -github.com/Azure/azure-sdk-for-go/sdk/azcore v0.14.1 h1:7JdDsau2B5IZc0d0CPvSMn8DxJ3GRBxtFS7OrZPIJdA= -github.com/Azure/azure-sdk-for-go/sdk/azcore v0.14.1/go.mod h1:pElNP+u99BvCZD+0jOlhI9OC/NB2IDTOTGZOZH0Qhq8= -github.com/Azure/azure-sdk-for-go/sdk/internal v0.5.0 h1:HG1ggl8L3ZkV/Ydanf7lKr5kkhhPGCpWdnr1J6v7cO4= -github.com/Azure/azure-sdk-for-go/sdk/internal v0.5.0/go.mod h1:k4KbFSunV/+0hOHL1vyFaPsiYQ1Vmvy1TBpmtvCDLZM= +github.com/Azure/azure-sdk-for-go/sdk/azcore v0.14.2 h1:jBp1eg+iY1S6SEjISakVfHmvDxfj8bg1Mw9JFwpCKag= +github.com/Azure/azure-sdk-for-go/sdk/azcore v0.14.2/go.mod h1:pElNP+u99BvCZD+0jOlhI9OC/NB2IDTOTGZOZH0Qhq8= +github.com/dnaeon/go-vcr v1.1.0 h1:ReYa/UBrRyQdant9B4fNHGoCNKw6qh6P0fsdGmZpR7c= +github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -19,5 +20,9 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestAddEntity-variables.yaml b/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestAddEntity-variables.yaml new file mode 100644 index 000000000000..dd3226b5e15b --- /dev/null +++ b/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestAddEntity-variables.yaml @@ -0,0 +1,5 @@ +--- +COSMOS_TABLES_ENDPOINT_SUFFIX: cosmos.azure.com +TABLES_COSMOS_ACCOUNT_NAME: chrisstablesprim +TABLES_PRIMARY_COSMOS_ACCOUNT_KEY: Kg== +randomSeed: "1617580856" diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestAddEntity.yaml b/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestAddEntity.yaml new file mode 100644 index 000000000000..f8993d0f4f77 --- /dev/null +++ b/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestAddEntity.yaml @@ -0,0 +1,121 @@ +--- +version: 1 +interactions: +- request: + body: '{"TableName":"gotable7ws4xms1mzf9z"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "36" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Mon, 05 Apr 2021 00:00:56 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/Tables + method: POST + response: + body: '{"TableName":"gotable7ws4xms1mzf9z","odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables/@Element"}' + headers: + Content-Type: + - application/json;odata=minimalmetadata + Date: + - Mon, 05 Apr 2021 00:00:56 GMT + Etag: + - W/"datetime'2021-04-05T00%3A00%3A56.5521416Z'" + Location: + - https://chrisstablesprim.table.cosmos.azure.com/Tables('gotable7ws4xms1mzf9z') + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 9ca87b9a-5e66-4ec1-97d0-0ea03fd04375 + status: 201 Created + code: 201 + duration: "" +- request: + body: '{"BoolProp":true,"IntProp":1,"PartitionKey":"partition","RowKey":"1","StringProp":"some + string 1"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "98" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + Prefer: + - return-no-content + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Mon, 05 Apr 2021 00:00:57 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/gotable7ws4xms1mzf9z + method: POST + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Mon, 05 Apr 2021 00:00:56 GMT + Etag: + - W/"datetime'2021-04-05T00%3A00%3A57.0277896Z'" + Location: + - https://chrisstablesprim.table.cosmos.azure.com/gotable7ws4xms1mzf9z(PartitionKey='partition',RowKey='1') + Preference-Applied: + - return-no-content + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 57a01ccb-9f82-4e3c-a2be-601d4ed96b9d + status: 204 No Content + code: 204 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Authorization: + - sanitized + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Mon, 05 Apr 2021 00:00:57 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/Tables('gotable7ws4xms1mzf9z') + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Mon, 05 Apr 2021 00:00:56 GMT + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - a515445a-2616-4e51-a4ea-bf4a788ad138 + status: 204 No Content + code: 204 + duration: "" diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestCreateTable-variables.yaml b/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestCreateTable-variables.yaml new file mode 100644 index 000000000000..5a403251353a --- /dev/null +++ b/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestCreateTable-variables.yaml @@ -0,0 +1,5 @@ +--- +COSMOS_TABLES_ENDPOINT_SUFFIX: cosmos.azure.com +TABLES_COSMOS_ACCOUNT_NAME: chrisstablesprim +TABLES_PRIMARY_COSMOS_ACCOUNT_KEY: Kg== +randomSeed: "1617573289" diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestCreateTable.yaml b/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestCreateTable.yaml new file mode 100644 index 000000000000..a60e34d514b1 --- /dev/null +++ b/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestCreateTable.yaml @@ -0,0 +1,75 @@ +--- +version: 1 +interactions: +- request: + body: '{"TableName":"gotable3atc3ia9qkkbd"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "36" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:49 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/Tables + method: POST + response: + body: '{"TableName":"gotable3atc3ia9qkkbd","odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables/@Element"}' + headers: + Content-Type: + - application/json;odata=minimalmetadata + Date: + - Sun, 04 Apr 2021 21:54:50 GMT + Etag: + - W/"datetime'2021-04-04T21%3A54%3A49.7968136Z'" + Location: + - https://chrisstablesprim.table.cosmos.azure.com/Tables('gotable3atc3ia9qkkbd') + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - b9386c93-2228-4a78-bcab-652c24994580 + status: 201 Created + code: 201 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Authorization: + - sanitized + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:50 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/Tables('gotable3atc3ia9qkkbd') + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Sun, 04 Apr 2021 21:54:50 GMT + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - f8cecc20-febd-48ed-950f-6fb532eb326d + status: 204 No Content + code: 204 + duration: "" diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestQuerySimpleEntity-variables.yaml b/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestQuerySimpleEntity-variables.yaml new file mode 100644 index 000000000000..05898e645159 --- /dev/null +++ b/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestQuerySimpleEntity-variables.yaml @@ -0,0 +1,5 @@ +--- +COSMOS_TABLES_ENDPOINT_SUFFIX: cosmos.azure.com +TABLES_COSMOS_ACCOUNT_NAME: chrisstablesprim +TABLES_PRIMARY_COSMOS_ACCOUNT_KEY: Kg== +randomSeed: "1617598959" diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestQuerySimpleEntity.yaml b/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestQuerySimpleEntity.yaml new file mode 100644 index 000000000000..4cc2c9ff4295 --- /dev/null +++ b/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestQuerySimpleEntity.yaml @@ -0,0 +1,342 @@ +--- +version: 1 +interactions: +- request: + body: '{"TableName":"gotabledtlot4b2qfkop"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "36" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Mon, 05 Apr 2021 05:02:39 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/Tables + method: POST + response: + body: '{"TableName":"gotabledtlot4b2qfkop","odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables/@Element"}' + headers: + Content-Type: + - application/json;odata=minimalmetadata + Date: + - Mon, 05 Apr 2021 05:02:40 GMT + Etag: + - W/"datetime'2021-04-05T05%3A02%3A40.1485832Z'" + Location: + - https://chrisstablesprim.table.cosmos.azure.com/Tables('gotabledtlot4b2qfkop') + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 0c4ccc90-a38a-47db-b904-ec327ee3f600 + status: 201 Created + code: 201 + duration: "" +- request: + body: '{"BoolProp":true,"IntProp":1,"PartitionKey":"partition","RowKey":"1","StringProp":"some + string 1"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "98" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + Prefer: + - return-no-content + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Mon, 05 Apr 2021 05:02:40 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/gotabledtlot4b2qfkop + method: POST + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Mon, 05 Apr 2021 05:02:40 GMT + Etag: + - W/"datetime'2021-04-05T05%3A02%3A40.7371784Z'" + Location: + - https://chrisstablesprim.table.cosmos.azure.com/gotabledtlot4b2qfkop(PartitionKey='partition',RowKey='1') + Preference-Applied: + - return-no-content + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 40cfa5d5-3867-469b-a5fe-aa61bfdded39 + status: 204 No Content + code: 204 + duration: "" +- request: + body: '{"BoolProp":true,"IntProp":2,"PartitionKey":"partition","RowKey":"2","StringProp":"some + string 2"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "98" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + Prefer: + - return-no-content + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Mon, 05 Apr 2021 05:02:40 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/gotabledtlot4b2qfkop + method: POST + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Mon, 05 Apr 2021 05:02:40 GMT + Etag: + - W/"datetime'2021-04-05T05%3A02%3A40.8410120Z'" + Location: + - https://chrisstablesprim.table.cosmos.azure.com/gotabledtlot4b2qfkop(PartitionKey='partition',RowKey='2') + Preference-Applied: + - return-no-content + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 3c31aac3-2859-47ad-abd7-8203e7f10b11 + status: 204 No Content + code: 204 + duration: "" +- request: + body: '{"BoolProp":true,"IntProp":3,"PartitionKey":"partition","RowKey":"3","StringProp":"some + string 3"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "98" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + Prefer: + - return-no-content + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Mon, 05 Apr 2021 05:02:41 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/gotabledtlot4b2qfkop + method: POST + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Mon, 05 Apr 2021 05:02:40 GMT + Etag: + - W/"datetime'2021-04-05T05%3A02%3A40.9537544Z'" + Location: + - https://chrisstablesprim.table.cosmos.azure.com/gotabledtlot4b2qfkop(PartitionKey='partition',RowKey='3') + Preference-Applied: + - return-no-content + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 0cd7d680-2274-4e93-9b7f-4d44cacff771 + status: 204 No Content + code: 204 + duration: "" +- request: + body: '{"BoolProp":true,"IntProp":4,"PartitionKey":"partition","RowKey":"4","StringProp":"some + string 4"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "98" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + Prefer: + - return-no-content + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Mon, 05 Apr 2021 05:02:41 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/gotabledtlot4b2qfkop + method: POST + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Mon, 05 Apr 2021 05:02:40 GMT + Etag: + - W/"datetime'2021-04-05T05%3A02%3A41.0579976Z'" + Location: + - https://chrisstablesprim.table.cosmos.azure.com/gotabledtlot4b2qfkop(PartitionKey='partition',RowKey='4') + Preference-Applied: + - return-no-content + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 2c18f6d8-af7f-4533-bf30-9243a8e31e18 + status: 204 No Content + code: 204 + duration: "" +- request: + body: '{"BoolProp":true,"IntProp":5,"PartitionKey":"partition","RowKey":"5","StringProp":"some + string 5"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "98" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + Prefer: + - return-no-content + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Mon, 05 Apr 2021 05:02:41 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/gotabledtlot4b2qfkop + method: POST + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Mon, 05 Apr 2021 05:02:40 GMT + Etag: + - W/"datetime'2021-04-05T05%3A02%3A41.1676680Z'" + Location: + - https://chrisstablesprim.table.cosmos.azure.com/gotabledtlot4b2qfkop(PartitionKey='partition',RowKey='5') + Preference-Applied: + - return-no-content + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 6ca39a1d-05ef-4d68-bfc2-5a79a009fdeb + status: 204 No Content + code: 204 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Mon, 05 Apr 2021 05:02:41 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/gotabledtlot4b2qfkop()?%24filter=RowKey+lt+%275%27 + method: GET + response: + body: '{"value":[{"odata.etag":"W/\"datetime''2021-04-05T05%3A02%3A40.7371784Z''\"","BoolProp":true,"IntProp":1,"PartitionKey":"partition","RowKey":"1","StringProp":"some + string 1","Timestamp":"2021-04-05T05:02:40.7371784Z"},{"odata.etag":"W/\"datetime''2021-04-05T05%3A02%3A40.8410120Z''\"","BoolProp":true,"IntProp":2,"PartitionKey":"partition","RowKey":"2","StringProp":"some + string 2","Timestamp":"2021-04-05T05:02:40.8410120Z"},{"odata.etag":"W/\"datetime''2021-04-05T05%3A02%3A40.9537544Z''\"","BoolProp":true,"IntProp":3,"PartitionKey":"partition","RowKey":"3","StringProp":"some + string 3","Timestamp":"2021-04-05T05:02:40.9537544Z"},{"odata.etag":"W/\"datetime''2021-04-05T05%3A02%3A41.0579976Z''\"","BoolProp":true,"IntProp":4,"PartitionKey":"partition","RowKey":"4","StringProp":"some + string 4","Timestamp":"2021-04-05T05:02:41.0579976Z"}],"odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#gotabledtlot4b2qfkop"}' + headers: + Content-Type: + - application/json;odata=minimalmetadata + Date: + - Mon, 05 Apr 2021 05:02:40 GMT + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 98466a7e-727a-4e2d-8f48-37039dae8f64 + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Authorization: + - sanitized + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Mon, 05 Apr 2021 05:02:41 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/Tables('gotabledtlot4b2qfkop') + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Mon, 05 Apr 2021 05:02:41 GMT + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - d7fa3ec7-64ad-43a3-8444-9f567b156391 + status: 204 No Content + code: 204 + duration: "" diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestServiceErrors-variables.yaml b/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestServiceErrors-variables.yaml new file mode 100644 index 000000000000..be617c45b1f0 --- /dev/null +++ b/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestServiceErrors-variables.yaml @@ -0,0 +1,5 @@ +--- +COSMOS_TABLES_ENDPOINT_SUFFIX: cosmos.azure.com +TABLES_COSMOS_ACCOUNT_NAME: chrisstablesprim +TABLES_PRIMARY_COSMOS_ACCOUNT_KEY: Kg== +randomSeed: "1617580014" diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestServiceErrors.yaml b/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestServiceErrors.yaml new file mode 100644 index 000000000000..0a52371c64d2 --- /dev/null +++ b/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestServiceErrors.yaml @@ -0,0 +1,113 @@ +--- +version: 1 +interactions: +- request: + body: '{"TableName":"gotable85g6eby7icg1v"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "36" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 23:46:54 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/Tables + method: POST + response: + body: '{"TableName":"gotable85g6eby7icg1v","odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables/@Element"}' + headers: + Content-Type: + - application/json;odata=minimalmetadata + Date: + - Sun, 04 Apr 2021 23:46:54 GMT + Etag: + - W/"datetime'2021-04-04T23%3A46%3A54.7914760Z'" + Location: + - https://chrisstablesprim.table.cosmos.azure.com/Tables('gotable85g6eby7icg1v') + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 947f9642-3c9b-475a-b3a0-6c04b3c2d40b + status: 201 Created + code: 201 + duration: "" +- request: + body: '{"TableName":"gotable85g6eby7icg1v"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "36" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 23:46:55 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/Tables + method: POST + response: + body: "{\"odata.error\":{\"code\":\"TableAlreadyExists\",\"message\":{\"lang\":\"en-us\",\"value\":\"The + specified table already exists.\\nRequestID:58f7ef4b-3378-4612-8f88-7fad883916de\\n\"}}}\r\n" + headers: + Content-Type: + - application/json;odata=minimalmetadata + Date: + - Sun, 04 Apr 2021 23:46:54 GMT + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 58f7ef4b-3378-4612-8f88-7fad883916de + status: 409 Conflict + code: 409 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Authorization: + - sanitized + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 23:46:55 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/Tables('gotable85g6eby7icg1v') + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Sun, 04 Apr 2021 23:46:54 GMT + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 40da51e2-3c50-4a09-a6e9-78663d0215c4 + status: 204 No Content + code: 204 + duration: "" diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestAddEntity-variables.yaml b/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestAddEntity-variables.yaml new file mode 100644 index 000000000000..b2ce8f9f7145 --- /dev/null +++ b/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestAddEntity-variables.yaml @@ -0,0 +1,5 @@ +--- +STORAGE_ENDPOINT_SUFFIX: core.windows.net +TABLES_PRIMARY_STORAGE_ACCOUNT_KEY: Kg== +TABLES_STORAGE_ACCOUNT_NAME: chrisstablesprim +randomSeed: "1617580855" diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestAddEntity.yaml b/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestAddEntity.yaml new file mode 100644 index 000000000000..e5b71baad0b6 --- /dev/null +++ b/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestAddEntity.yaml @@ -0,0 +1,139 @@ +--- +version: 1 +interactions: +- request: + body: '{"TableName":"gotableldjhskq166plj"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "36" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Mon, 05 Apr 2021 00:00:55 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/Tables + method: POST + response: + body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#Tables/@Element","TableName":"gotableldjhskq166plj"}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 + Date: + - Mon, 05 Apr 2021 00:00:55 GMT + Location: + - https://chrisstablesprim.table.core.windows.net/Tables('gotableldjhskq166plj') + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 204673eb-b002-003b-64ae-2971b0000000 + X-Ms-Version: + - "2019-02-02" + status: 201 Created + code: 201 + duration: "" +- request: + body: '{"BoolProp":true,"IntProp":1,"PartitionKey":"partition","RowKey":"1","StringProp":"some + string 1"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "98" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + Prefer: + - return-no-content + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Mon, 05 Apr 2021 00:00:55 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/gotableldjhskq166plj + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://chrisstablesprim.table.core.windows.net/gotableldjhskq166plj(PartitionKey='partition',RowKey='1') + Date: + - Mon, 05 Apr 2021 00:00:55 GMT + Etag: + - W/"datetime'2021-04-05T00%3A00%3A55.7477359Z'" + Location: + - https://chrisstablesprim.table.core.windows.net/gotableldjhskq166plj(PartitionKey='partition',RowKey='1') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 204673f0-b002-003b-67ae-2971b0000000 + X-Ms-Version: + - "2019-02-02" + status: 204 No Content + code: 204 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Authorization: + - sanitized + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Mon, 05 Apr 2021 00:00:55 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/Tables('gotableldjhskq166plj') + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Mon, 05 Apr 2021 00:00:55 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 204673f1-b002-003b-68ae-2971b0000000 + X-Ms-Version: + - "2019-02-02" + status: 204 No Content + code: 204 + duration: "" diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestCreateTable-variables.yaml b/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestCreateTable-variables.yaml new file mode 100644 index 000000000000..db82b723a5c5 --- /dev/null +++ b/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestCreateTable-variables.yaml @@ -0,0 +1,5 @@ +--- +STORAGE_ENDPOINT_SUFFIX: core.windows.net +TABLES_PRIMARY_STORAGE_ACCOUNT_KEY: Kg== +TABLES_STORAGE_ACCOUNT_NAME: chrisstablesprim +randomSeed: "1617573288" diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestCreateTable.yaml b/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestCreateTable.yaml new file mode 100644 index 000000000000..6ef28bf11ac7 --- /dev/null +++ b/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestCreateTable.yaml @@ -0,0 +1,85 @@ +--- +version: 1 +interactions: +- request: + body: '{"TableName":"gotable9uourkrfkri2m"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "36" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:48 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/Tables + method: POST + response: + body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#Tables/@Element","TableName":"gotable9uourkrfkri2m"}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 + Date: + - Sun, 04 Apr 2021 21:54:48 GMT + Location: + - https://chrisstablesprim.table.core.windows.net/Tables('gotable9uourkrfkri2m') + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - aa171ae1-c002-0053-399d-291720000000 + X-Ms-Version: + - "2019-02-02" + status: 201 Created + code: 201 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Authorization: + - sanitized + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:48 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/Tables('gotable9uourkrfkri2m') + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Sun, 04 Apr 2021 21:54:48 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - aa171aec-c002-0053-419d-291720000000 + X-Ms-Version: + - "2019-02-02" + status: 204 No Content + code: 204 + duration: "" diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestQuerySimpleEntity-variables.yaml b/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestQuerySimpleEntity-variables.yaml new file mode 100644 index 000000000000..7a6b1b1ab41d --- /dev/null +++ b/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestQuerySimpleEntity-variables.yaml @@ -0,0 +1,5 @@ +--- +STORAGE_ENDPOINT_SUFFIX: core.windows.net +TABLES_PRIMARY_STORAGE_ACCOUNT_KEY: Kg== +TABLES_STORAGE_ACCOUNT_NAME: chrisstablesprim +randomSeed: "1617598958" diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestQuerySimpleEntity.yaml b/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestQuerySimpleEntity.yaml new file mode 100644 index 000000000000..1735178553e0 --- /dev/null +++ b/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestQuerySimpleEntity.yaml @@ -0,0 +1,398 @@ +--- +version: 1 +interactions: +- request: + body: '{"TableName":"gotablev9ymy16fzote2"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "36" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Mon, 05 Apr 2021 05:02:38 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/Tables + method: POST + response: + body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#Tables/@Element","TableName":"gotablev9ymy16fzote2"}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 + Date: + - Mon, 05 Apr 2021 05:02:37 GMT + Location: + - https://chrisstablesprim.table.core.windows.net/Tables('gotablev9ymy16fzote2') + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 95cfebe3-e002-0019-49d8-29b4af000000 + X-Ms-Version: + - "2019-02-02" + status: 201 Created + code: 201 + duration: "" +- request: + body: '{"BoolProp":true,"IntProp":1,"PartitionKey":"partition","RowKey":"1","StringProp":"some + string 1"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "98" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + Prefer: + - return-no-content + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Mon, 05 Apr 2021 05:02:38 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2 + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2(PartitionKey='partition',RowKey='1') + Date: + - Mon, 05 Apr 2021 05:02:37 GMT + Etag: + - W/"datetime'2021-04-05T05%3A02%3A38.4885381Z'" + Location: + - https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2(PartitionKey='partition',RowKey='1') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 95cfebec-e002-0019-50d8-29b4af000000 + X-Ms-Version: + - "2019-02-02" + status: 204 No Content + code: 204 + duration: "" +- request: + body: '{"BoolProp":true,"IntProp":2,"PartitionKey":"partition","RowKey":"2","StringProp":"some + string 2"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "98" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + Prefer: + - return-no-content + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Mon, 05 Apr 2021 05:02:38 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2 + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2(PartitionKey='partition',RowKey='2') + Date: + - Mon, 05 Apr 2021 05:02:37 GMT + Etag: + - W/"datetime'2021-04-05T05%3A02%3A38.5946142Z'" + Location: + - https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2(PartitionKey='partition',RowKey='2') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 95cfebf1-e002-0019-55d8-29b4af000000 + X-Ms-Version: + - "2019-02-02" + status: 204 No Content + code: 204 + duration: "" +- request: + body: '{"BoolProp":true,"IntProp":3,"PartitionKey":"partition","RowKey":"3","StringProp":"some + string 3"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "98" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + Prefer: + - return-no-content + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Mon, 05 Apr 2021 05:02:38 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2 + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2(PartitionKey='partition',RowKey='3') + Date: + - Mon, 05 Apr 2021 05:02:38 GMT + Etag: + - W/"datetime'2021-04-05T05%3A02%3A38.6866808Z'" + Location: + - https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2(PartitionKey='partition',RowKey='3') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 95cfebf3-e002-0019-57d8-29b4af000000 + X-Ms-Version: + - "2019-02-02" + status: 204 No Content + code: 204 + duration: "" +- request: + body: '{"BoolProp":true,"IntProp":4,"PartitionKey":"partition","RowKey":"4","StringProp":"some + string 4"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "98" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + Prefer: + - return-no-content + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Mon, 05 Apr 2021 05:02:38 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2 + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2(PartitionKey='partition',RowKey='4') + Date: + - Mon, 05 Apr 2021 05:02:38 GMT + Etag: + - W/"datetime'2021-04-05T05%3A02%3A38.7727417Z'" + Location: + - https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2(PartitionKey='partition',RowKey='4') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 95cfebf5-e002-0019-59d8-29b4af000000 + X-Ms-Version: + - "2019-02-02" + status: 204 No Content + code: 204 + duration: "" +- request: + body: '{"BoolProp":true,"IntProp":5,"PartitionKey":"partition","RowKey":"5","StringProp":"some + string 5"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "98" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + Prefer: + - return-no-content + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Mon, 05 Apr 2021 05:02:38 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2 + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2(PartitionKey='partition',RowKey='5') + Date: + - Mon, 05 Apr 2021 05:02:38 GMT + Etag: + - W/"datetime'2021-04-05T05%3A02%3A38.8487963Z'" + Location: + - https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2(PartitionKey='partition',RowKey='5') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 95cfebfb-e002-0019-5cd8-29b4af000000 + X-Ms-Version: + - "2019-02-02" + status: 204 No Content + code: 204 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Mon, 05 Apr 2021 05:02:39 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2()?%24filter=RowKey+lt+%275%27 + method: GET + response: + body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#gotablev9ymy16fzote2","value":[{"odata.etag":"W/\"datetime''2021-04-05T05%3A02%3A38.4885381Z''\"","PartitionKey":"partition","RowKey":"1","Timestamp":"2021-04-05T05:02:38.4885381Z","BoolProp":true,"IntProp":1,"StringProp":"some + string 1"},{"odata.etag":"W/\"datetime''2021-04-05T05%3A02%3A38.5946142Z''\"","PartitionKey":"partition","RowKey":"2","Timestamp":"2021-04-05T05:02:38.5946142Z","BoolProp":true,"IntProp":2,"StringProp":"some + string 2"},{"odata.etag":"W/\"datetime''2021-04-05T05%3A02%3A38.6866808Z''\"","PartitionKey":"partition","RowKey":"3","Timestamp":"2021-04-05T05:02:38.6866808Z","BoolProp":true,"IntProp":3,"StringProp":"some + string 3"},{"odata.etag":"W/\"datetime''2021-04-05T05%3A02%3A38.7727417Z''\"","PartitionKey":"partition","RowKey":"4","Timestamp":"2021-04-05T05:02:38.7727417Z","BoolProp":true,"IntProp":4,"StringProp":"some + string 4"}]}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 + Date: + - Mon, 05 Apr 2021 05:02:38 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 95cfebfe-e002-0019-5ed8-29b4af000000 + X-Ms-Version: + - "2019-02-02" + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Authorization: + - sanitized + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Mon, 05 Apr 2021 05:02:39 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/Tables('gotablev9ymy16fzote2') + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Mon, 05 Apr 2021 05:02:38 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 95cfec00-e002-0019-60d8-29b4af000000 + X-Ms-Version: + - "2019-02-02" + status: 204 No Content + code: 204 + duration: "" diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestServiceErrors-variables.yaml b/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestServiceErrors-variables.yaml new file mode 100644 index 000000000000..db3e9cbbe8a7 --- /dev/null +++ b/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestServiceErrors-variables.yaml @@ -0,0 +1,5 @@ +--- +STORAGE_ENDPOINT_SUFFIX: core.windows.net +TABLES_PRIMARY_STORAGE_ACCOUNT_KEY: Kg== +TABLES_STORAGE_ACCOUNT_NAME: chrisstablesprim +randomSeed: "1617580013" diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestServiceErrors.yaml b/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestServiceErrors.yaml new file mode 100644 index 000000000000..65a3e042f9f4 --- /dev/null +++ b/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestServiceErrors.yaml @@ -0,0 +1,129 @@ +--- +version: 1 +interactions: +- request: + body: '{"TableName":"gotable4gghmbc0umbca"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "36" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 23:46:53 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/Tables + method: POST + response: + body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#Tables/@Element","TableName":"gotable4gghmbc0umbca"}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 + Date: + - Sun, 04 Apr 2021 23:46:53 GMT + Location: + - https://chrisstablesprim.table.core.windows.net/Tables('gotable4gghmbc0umbca') + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 89afb2ba-b002-0066-1aac-297b34000000 + X-Ms-Version: + - "2019-02-02" + status: 201 Created + code: 201 + duration: "" +- request: + body: '{"TableName":"gotable4gghmbc0umbca"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "36" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 23:46:54 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/Tables + method: POST + response: + body: '{"odata.error":{"code":"TableAlreadyExists","message":{"lang":"en-US","value":"The + table specified already exists.\nRequestId:89afb2c5-b002-0066-23ac-297b34000000\nTime:2021-04-04T23:46:53.9829008Z"}}}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 + Date: + - Sun, 04 Apr 2021 23:46:53 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 89afb2c5-b002-0066-23ac-297b34000000 + X-Ms-Version: + - "2019-02-02" + status: 409 Conflict + code: 409 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Authorization: + - sanitized + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 23:46:54 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/Tables('gotable4gghmbc0umbca') + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Sun, 04 Apr 2021 23:46:53 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 89afb2cd-b002-0066-2aac-297b34000000 + X-Ms-Version: + - "2019-02-02" + status: 204 No Content + code: 204 + duration: "" diff --git a/sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestCreateTable-variables.yaml b/sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestCreateTable-variables.yaml new file mode 100644 index 000000000000..7c9e2af36ee8 --- /dev/null +++ b/sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestCreateTable-variables.yaml @@ -0,0 +1,5 @@ +--- +COSMOS_TABLES_ENDPOINT_SUFFIX: cosmos.azure.com +TABLES_COSMOS_ACCOUNT_NAME: chrisstablesprim +TABLES_PRIMARY_COSMOS_ACCOUNT_KEY: Kg== +randomSeed: "1617573293" diff --git a/sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestCreateTable.yaml b/sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestCreateTable.yaml new file mode 100644 index 000000000000..032f93240511 --- /dev/null +++ b/sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestCreateTable.yaml @@ -0,0 +1,75 @@ +--- +version: 1 +interactions: +- request: + body: '{"TableName":"gotablecwmvbx3xi23m7"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "36" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:53 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/Tables + method: POST + response: + body: '{"TableName":"gotablecwmvbx3xi23m7","odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables/@Element"}' + headers: + Content-Type: + - application/json;odata=minimalmetadata + Date: + - Sun, 04 Apr 2021 21:54:53 GMT + Etag: + - W/"datetime'2021-04-04T21%3A54%3A53.3743624Z'" + Location: + - https://chrisstablesprim.table.cosmos.azure.com/Tables('gotablecwmvbx3xi23m7') + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 33edc858-c2fc-436f-a0a0-8f909cfd1114 + status: 201 Created + code: 201 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Authorization: + - sanitized + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:53 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/Tables('gotablecwmvbx3xi23m7') + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Sun, 04 Apr 2021 21:54:53 GMT + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 654da1b1-025b-451e-8d64-d3c4afe7739a + status: 204 No Content + code: 204 + duration: "" diff --git a/sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestQueryTable-variables.yaml b/sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestQueryTable-variables.yaml new file mode 100644 index 000000000000..e1d3c746ac8b --- /dev/null +++ b/sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestQueryTable-variables.yaml @@ -0,0 +1,5 @@ +--- +COSMOS_TABLES_ENDPOINT_SUFFIX: cosmos.azure.com +TABLES_COSMOS_ACCOUNT_NAME: chrisstablesprim +TABLES_PRIMARY_COSMOS_ACCOUNT_KEY: Kg== +randomSeed: "1617573294" diff --git a/sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestQueryTable.yaml b/sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestQueryTable.yaml new file mode 100644 index 000000000000..4451edbf754c --- /dev/null +++ b/sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestQueryTable.yaml @@ -0,0 +1,499 @@ +--- +version: 1 +interactions: +- request: + body: '{"TableName":"zzza6868drab2e097oxu"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "36" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:54 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/Tables + method: POST + response: + body: '{"TableName":"zzza6868drab2e097oxu","odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables/@Element"}' + headers: + Content-Type: + - application/json;odata=minimalmetadata + Date: + - Sun, 04 Apr 2021 21:54:53 GMT + Etag: + - W/"datetime'2021-04-04T21%3A54%3A54.2225416Z'" + Location: + - https://chrisstablesprim.table.cosmos.azure.com/Tables('zzza6868drab2e097oxu') + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - b9dd1425-f416-44cd-9759-fa6ddc763d8e + status: 201 Created + code: 201 + duration: "" +- request: + body: '{"TableName":"zzza47kqkxef1dqg6hk5"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "36" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:54 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/Tables + method: POST + response: + body: '{"TableName":"zzza47kqkxef1dqg6hk5","odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables/@Element"}' + headers: + Content-Type: + - application/json;odata=minimalmetadata + Date: + - Sun, 04 Apr 2021 21:54:55 GMT + Etag: + - W/"datetime'2021-04-04T21%3A54%3A54.7395592Z'" + Location: + - https://chrisstablesprim.table.cosmos.azure.com/Tables('zzza47kqkxef1dqg6hk5') + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 7cc0bdc4-bc2e-41a5-a9d5-718481425834 + status: 201 Created + code: 201 + duration: "" +- request: + body: '{"TableName":"zzzancjsimv46ssmus2y"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "36" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:55 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/Tables + method: POST + response: + body: '{"TableName":"zzzancjsimv46ssmus2y","odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables/@Element"}' + headers: + Content-Type: + - application/json;odata=minimalmetadata + Date: + - Sun, 04 Apr 2021 21:54:55 GMT + Etag: + - W/"datetime'2021-04-04T21%3A54%3A55.2994824Z'" + Location: + - https://chrisstablesprim.table.cosmos.azure.com/Tables('zzzancjsimv46ssmus2y') + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 458c58e3-3247-448a-a542-de9f20e68872 + status: 201 Created + code: 201 + duration: "" +- request: + body: '{"TableName":"zzzau7wd11jeadrhkzia"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "36" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:55 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/Tables + method: POST + response: + body: '{"TableName":"zzzau7wd11jeadrhkzia","odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables/@Element"}' + headers: + Content-Type: + - application/json;odata=minimalmetadata + Date: + - Sun, 04 Apr 2021 21:54:56 GMT + Etag: + - W/"datetime'2021-04-04T21%3A54%3A55.8298120Z'" + Location: + - https://chrisstablesprim.table.cosmos.azure.com/Tables('zzzau7wd11jeadrhkzia') + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - e08277e1-0ac2-4cb7-a9c2-3ad4d593d33e + status: 201 Created + code: 201 + duration: "" +- request: + body: '{"TableName":"zzzbm74eob1xykl1zb71"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "36" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:56 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/Tables + method: POST + response: + body: '{"TableName":"zzzbm74eob1xykl1zb71","odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables/@Element"}' + headers: + Content-Type: + - application/json;odata=minimalmetadata + Date: + - Sun, 04 Apr 2021 21:54:56 GMT + Etag: + - W/"datetime'2021-04-04T21%3A54%3A56.4097032Z'" + Location: + - https://chrisstablesprim.table.cosmos.azure.com/Tables('zzzbm74eob1xykl1zb71') + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - aba90f45-d352-46e5-8d0b-32d749a29ac3 + status: 201 Created + code: 201 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:56 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/Tables?%24filter=TableName+ge+%27zzza%27+and+TableName+lt+%27zzzb%27 + method: GET + response: + body: '{"value":[{"TableName":"zzza6868drab2e097oxu"},{"TableName":"zzza47kqkxef1dqg6hk5"},{"TableName":"zzzancjsimv46ssmus2y"},{"TableName":"zzzau7wd11jeadrhkzia"}],"odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables"}' + headers: + Content-Type: + - application/json;odata=minimalmetadata + Date: + - Sun, 04 Apr 2021 21:54:56 GMT + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - e277f56f-be38-4847-bcc7-d404818cc2a4 + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:57 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/Tables?%24filter=TableName+ge+%27zzza%27+and+TableName+lt+%27zzzb%27&%24top=2 + method: GET + response: + body: '{"value":[{"TableName":"zzza6868drab2e097oxu"},{"TableName":"zzza47kqkxef1dqg6hk5"}],"odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables"}' + headers: + Content-Type: + - application/json;odata=minimalmetadata + Date: + - Sun, 04 Apr 2021 21:54:56 GMT + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Continuation-Nexttablename: + - -RID:~-mg9ANt+LD8=#RT:1#TRC:2 + X-Ms-Request-Id: + - 89b83810-e42f-46f9-a174-3a0cd1ebd42b + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:57 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/Tables?%24filter=TableName+ge+%27zzza%27+and+TableName+lt+%27zzzb%27&%24top=2&NextTableName=-RID%3A~-mg9ANt%2BLD8%3D%23RT%3A1%23TRC%3A2 + method: GET + response: + body: '{"value":[{"TableName":"zzzancjsimv46ssmus2y"},{"TableName":"zzzau7wd11jeadrhkzia"}],"odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables"}' + headers: + Content-Type: + - application/json;odata=minimalmetadata + Date: + - Sun, 04 Apr 2021 21:54:56 GMT + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Continuation-Nexttablename: + - -RID:~-mg9AOab5rE=#RT:2#TRC:4 + X-Ms-Request-Id: + - 5b359f2a-f01b-4b51-88b8-f555384be342 + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:57 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/Tables?%24filter=TableName+ge+%27zzza%27+and+TableName+lt+%27zzzb%27&%24top=2&NextTableName=-RID%3A~-mg9AOab5rE%3D%23RT%3A2%23TRC%3A4 + method: GET + response: + body: '{"value":[],"odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables"}' + headers: + Content-Type: + - application/json;odata=minimalmetadata + Date: + - Sun, 04 Apr 2021 21:54:56 GMT + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - bac31683-48dc-4dba-86b7-5299f8f80b14 + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Authorization: + - sanitized + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:57 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/Tables('zzza6868drab2e097oxu') + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Sun, 04 Apr 2021 21:54:57 GMT + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 4e2b7f94-e9a9-4397-9ec1-c4808f908cf0 + status: 204 No Content + code: 204 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Authorization: + - sanitized + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:57 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/Tables('zzza47kqkxef1dqg6hk5') + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Sun, 04 Apr 2021 21:54:57 GMT + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 0c5dda5b-2983-493f-8114-90378a12a073 + status: 204 No Content + code: 204 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Authorization: + - sanitized + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:58 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/Tables('zzzancjsimv46ssmus2y') + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Sun, 04 Apr 2021 21:54:57 GMT + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 7f4c8bcf-9801-493b-90b8-84ee3935af02 + status: 204 No Content + code: 204 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Authorization: + - sanitized + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:58 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/Tables('zzzau7wd11jeadrhkzia') + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Sun, 04 Apr 2021 21:54:58 GMT + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - a05000dd-1cfe-4256-88b7-e6be74a2d7df + status: 204 No Content + code: 204 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Authorization: + - sanitized + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:58 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/Tables('zzzbm74eob1xykl1zb71') + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Sun, 04 Apr 2021 21:54:58 GMT + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 81acb8ac-7460-4aa8-b548-e426c88aba21 + status: 204 No Content + code: 204 + duration: "" diff --git a/sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestServiceErrors-variables.yaml b/sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestServiceErrors-variables.yaml new file mode 100644 index 000000000000..760bc4d4fdfb --- /dev/null +++ b/sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestServiceErrors-variables.yaml @@ -0,0 +1,5 @@ +--- +COSMOS_TABLES_ENDPOINT_SUFFIX: cosmos.azure.com +TABLES_COSMOS_ACCOUNT_NAME: chrisstablesprim +TABLES_PRIMARY_COSMOS_ACCOUNT_KEY: Kg== +randomSeed: "1617573550" diff --git a/sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestServiceErrors.yaml b/sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestServiceErrors.yaml new file mode 100644 index 000000000000..d3b9bf432eb8 --- /dev/null +++ b/sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestServiceErrors.yaml @@ -0,0 +1,113 @@ +--- +version: 1 +interactions: +- request: + body: '{"TableName":"gotable5hickrxl8lpbo"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "36" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:59:10 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/Tables + method: POST + response: + body: '{"TableName":"gotable5hickrxl8lpbo","odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables/@Element"}' + headers: + Content-Type: + - application/json;odata=minimalmetadata + Date: + - Sun, 04 Apr 2021 21:59:11 GMT + Etag: + - W/"datetime'2021-04-04T21%3A59%3A10.9652488Z'" + Location: + - https://chrisstablesprim.table.cosmos.azure.com/Tables('gotable5hickrxl8lpbo') + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - a5903255-58e5-4c43-bad9-f5e92cd5bd68 + status: 201 Created + code: 201 + duration: "" +- request: + body: '{"TableName":"gotable5hickrxl8lpbo"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "36" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:59:11 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/Tables + method: POST + response: + body: "{\"odata.error\":{\"code\":\"TableAlreadyExists\",\"message\":{\"lang\":\"en-us\",\"value\":\"The + specified table already exists.\\nRequestID:e216471c-9dae-4105-99a9-66a274775cce\\n\"}}}\r\n" + headers: + Content-Type: + - application/json;odata=minimalmetadata + Date: + - Sun, 04 Apr 2021 21:59:11 GMT + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - e216471c-9dae-4105-99a9-66a274775cce + status: 409 Conflict + code: 409 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Authorization: + - sanitized + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:59:11 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/Tables('gotable5hickrxl8lpbo') + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Sun, 04 Apr 2021 21:59:11 GMT + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - c8bbfa46-7d78-46af-a6cb-b54bd57237af + status: 204 No Content + code: 204 + duration: "" diff --git a/sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestCreateTable-variables.yaml b/sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestCreateTable-variables.yaml new file mode 100644 index 000000000000..9b7c965397f6 --- /dev/null +++ b/sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestCreateTable-variables.yaml @@ -0,0 +1,5 @@ +--- +STORAGE_ENDPOINT_SUFFIX: core.windows.net +TABLES_PRIMARY_STORAGE_ACCOUNT_KEY: Kg== +TABLES_STORAGE_ACCOUNT_NAME: chrisstablesprim +randomSeed: "1617573291" diff --git a/sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestCreateTable.yaml b/sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestCreateTable.yaml new file mode 100644 index 000000000000..f5f90205815d --- /dev/null +++ b/sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestCreateTable.yaml @@ -0,0 +1,85 @@ +--- +version: 1 +interactions: +- request: + body: '{"TableName":"gotablep06y44pq0dcqy"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "36" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:51 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/Tables + method: POST + response: + body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#Tables/@Element","TableName":"gotablep06y44pq0dcqy"}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 + Date: + - Sun, 04 Apr 2021 21:54:51 GMT + Location: + - https://chrisstablesprim.table.core.windows.net/Tables('gotablep06y44pq0dcqy') + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - aa171c82-c002-0053-409d-291720000000 + X-Ms-Version: + - "2019-02-02" + status: 201 Created + code: 201 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Authorization: + - sanitized + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:51 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/Tables('gotablep06y44pq0dcqy') + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Sun, 04 Apr 2021 21:54:51 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - aa171c8d-c002-0053-4a9d-291720000000 + X-Ms-Version: + - "2019-02-02" + status: 204 No Content + code: 204 + duration: "" diff --git a/sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestQueryTable-variables.yaml b/sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestQueryTable-variables.yaml new file mode 100644 index 000000000000..9b7c965397f6 --- /dev/null +++ b/sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestQueryTable-variables.yaml @@ -0,0 +1,5 @@ +--- +STORAGE_ENDPOINT_SUFFIX: core.windows.net +TABLES_PRIMARY_STORAGE_ACCOUNT_KEY: Kg== +TABLES_STORAGE_ACCOUNT_NAME: chrisstablesprim +randomSeed: "1617573291" diff --git a/sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestQueryTable.yaml b/sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestQueryTable.yaml new file mode 100644 index 000000000000..2431a475cb56 --- /dev/null +++ b/sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestQueryTable.yaml @@ -0,0 +1,532 @@ +--- +version: 1 +interactions: +- request: + body: '{"TableName":"zzzap06y44pq0dcqyefd"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "36" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:51 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/Tables + method: POST + response: + body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#Tables/@Element","TableName":"zzzap06y44pq0dcqyefd"}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 + Date: + - Sun, 04 Apr 2021 21:54:51 GMT + Location: + - https://chrisstablesprim.table.core.windows.net/Tables('zzzap06y44pq0dcqyefd') + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - aa171c98-c002-0053-539d-291720000000 + X-Ms-Version: + - "2019-02-02" + status: 201 Created + code: 201 + duration: "" +- request: + body: '{"TableName":"zzzas5q9cqk9i1o44v25"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "36" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:52 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/Tables + method: POST + response: + body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#Tables/@Element","TableName":"zzzas5q9cqk9i1o44v25"}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 + Date: + - Sun, 04 Apr 2021 21:54:51 GMT + Location: + - https://chrisstablesprim.table.core.windows.net/Tables('zzzas5q9cqk9i1o44v25') + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - aa171ca1-c002-0053-5b9d-291720000000 + X-Ms-Version: + - "2019-02-02" + status: 201 Created + code: 201 + duration: "" +- request: + body: '{"TableName":"zzzavphdrg4ipo7z4boc"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "36" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:52 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/Tables + method: POST + response: + body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#Tables/@Element","TableName":"zzzavphdrg4ipo7z4boc"}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 + Date: + - Sun, 04 Apr 2021 21:54:51 GMT + Location: + - https://chrisstablesprim.table.core.windows.net/Tables('zzzavphdrg4ipo7z4boc') + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - aa171ca9-c002-0053-629d-291720000000 + X-Ms-Version: + - "2019-02-02" + status: 201 Created + code: 201 + duration: "" +- request: + body: '{"TableName":"zzzanoa2c4lxhmr55w1n"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "36" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:52 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/Tables + method: POST + response: + body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#Tables/@Element","TableName":"zzzanoa2c4lxhmr55w1n"}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 + Date: + - Sun, 04 Apr 2021 21:54:51 GMT + Location: + - https://chrisstablesprim.table.core.windows.net/Tables('zzzanoa2c4lxhmr55w1n') + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - aa171cb5-c002-0053-6c9d-291720000000 + X-Ms-Version: + - "2019-02-02" + status: 201 Created + code: 201 + duration: "" +- request: + body: '{"TableName":"zzzbq0ics0v4b1nbyytz"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "36" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:52 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/Tables + method: POST + response: + body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#Tables/@Element","TableName":"zzzbq0ics0v4b1nbyytz"}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 + Date: + - Sun, 04 Apr 2021 21:54:51 GMT + Location: + - https://chrisstablesprim.table.core.windows.net/Tables('zzzbq0ics0v4b1nbyytz') + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - aa171cbe-c002-0053-739d-291720000000 + X-Ms-Version: + - "2019-02-02" + status: 201 Created + code: 201 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:52 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/Tables?%24filter=TableName+ge+%27zzza%27+and+TableName+lt+%27zzzb%27 + method: GET + response: + body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#Tables","value":[{"TableName":"zzzanoa2c4lxhmr55w1n"},{"TableName":"zzzap06y44pq0dcqyefd"},{"TableName":"zzzas5q9cqk9i1o44v25"},{"TableName":"zzzavphdrg4ipo7z4boc"}]}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 + Date: + - Sun, 04 Apr 2021 21:54:51 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - aa171ccc-c002-0053-7f9d-291720000000 + X-Ms-Version: + - "2019-02-02" + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:52 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/Tables?%24filter=TableName+ge+%27zzza%27+and+TableName+lt+%27zzzb%27&%24top=2 + method: GET + response: + body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#Tables","value":[{"TableName":"zzzanoa2c4lxhmr55w1n"},{"TableName":"zzzap06y44pq0dcqyefd"}]}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 + Date: + - Sun, 04 Apr 2021 21:54:51 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Continuation-Nexttablename: + - 1!52!enp6YXM1cTljcWs5aTFvNDR2MjUBMDFkNzI5OWQyM2U4NjU2Yw-- + X-Ms-Request-Id: + - aa171ce3-c002-0053-159d-291720000000 + X-Ms-Version: + - "2019-02-02" + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:52 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/Tables?%24filter=TableName+ge+%27zzza%27+and+TableName+lt+%27zzzb%27&%24top=2&NextTableName=1%2152%21enp6YXM1cTljcWs5aTFvNDR2MjUBMDFkNzI5OWQyM2U4NjU2Yw-- + method: GET + response: + body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#Tables","value":[{"TableName":"zzzas5q9cqk9i1o44v25"},{"TableName":"zzzavphdrg4ipo7z4boc"}]}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 + Date: + - Sun, 04 Apr 2021 21:54:51 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - aa171cf4-c002-0053-269d-291720000000 + X-Ms-Version: + - "2019-02-02" + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Authorization: + - sanitized + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:52 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/Tables('zzzap06y44pq0dcqyefd') + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Sun, 04 Apr 2021 21:54:52 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - aa171d07-c002-0053-369d-291720000000 + X-Ms-Version: + - "2019-02-02" + status: 204 No Content + code: 204 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Authorization: + - sanitized + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:52 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/Tables('zzzas5q9cqk9i1o44v25') + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Sun, 04 Apr 2021 21:54:52 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - aa171d16-c002-0053-459d-291720000000 + X-Ms-Version: + - "2019-02-02" + status: 204 No Content + code: 204 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Authorization: + - sanitized + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:52 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/Tables('zzzavphdrg4ipo7z4boc') + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Sun, 04 Apr 2021 21:54:52 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - aa171d2a-c002-0053-599d-291720000000 + X-Ms-Version: + - "2019-02-02" + status: 204 No Content + code: 204 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Authorization: + - sanitized + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:52 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/Tables('zzzanoa2c4lxhmr55w1n') + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Sun, 04 Apr 2021 21:54:52 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - aa171d3d-c002-0053-6c9d-291720000000 + X-Ms-Version: + - "2019-02-02" + status: 204 No Content + code: 204 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Authorization: + - sanitized + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:54:53 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/Tables('zzzbq0ics0v4b1nbyytz') + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Sun, 04 Apr 2021 21:54:52 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - aa171d51-c002-0053-7d9d-291720000000 + X-Ms-Version: + - "2019-02-02" + status: 204 No Content + code: 204 + duration: "" diff --git a/sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestServiceErrors-variables.yaml b/sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestServiceErrors-variables.yaml new file mode 100644 index 000000000000..3f5acca6cabc --- /dev/null +++ b/sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestServiceErrors-variables.yaml @@ -0,0 +1,5 @@ +--- +STORAGE_ENDPOINT_SUFFIX: core.windows.net +TABLES_PRIMARY_STORAGE_ACCOUNT_KEY: Kg== +TABLES_STORAGE_ACCOUNT_NAME: chrisstablesprim +randomSeed: "1617573550" diff --git a/sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestServiceErrors.yaml b/sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestServiceErrors.yaml new file mode 100644 index 000000000000..55b918ae4d98 --- /dev/null +++ b/sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestServiceErrors.yaml @@ -0,0 +1,129 @@ +--- +version: 1 +interactions: +- request: + body: '{"TableName":"gotable5hickrxl8lpbo"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "36" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:59:10 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/Tables + method: POST + response: + body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#Tables/@Element","TableName":"gotable5hickrxl8lpbo"}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 + Date: + - Sun, 04 Apr 2021 21:59:09 GMT + Location: + - https://chrisstablesprim.table.core.windows.net/Tables('gotable5hickrxl8lpbo') + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - a5bfa352-3002-0057-209d-299a27000000 + X-Ms-Version: + - "2019-02-02" + status: 201 Created + code: 201 + duration: "" +- request: + body: '{"TableName":"gotable5hickrxl8lpbo"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "36" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:59:10 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/Tables + method: POST + response: + body: '{"odata.error":{"code":"TableAlreadyExists","message":{"lang":"en-US","value":"The + table specified already exists.\nRequestId:a5bfa358-3002-0057-259d-299a27000000\nTime:2021-04-04T21:59:10.6883876Z"}}}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 + Date: + - Sun, 04 Apr 2021 21:59:10 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - a5bfa358-3002-0057-259d-299a27000000 + X-Ms-Version: + - "2019-02-02" + status: 409 Conflict + code: 409 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Authorization: + - sanitized + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 04 Apr 2021 21:59:10 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/Tables('gotable5hickrxl8lpbo') + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Sun, 04 Apr 2021 21:59:10 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - a5bfa35c-3002-0057-299d-299a27000000 + X-Ms-Version: + - "2019-02-02" + status: 204 No Content + code: 204 + duration: "" diff --git a/sdk/tables/aztables/tableClient.go b/sdk/tables/aztables/tableClient.go index edc74ece6075..e72aebab42ef 100644 --- a/sdk/tables/aztables/tableClient.go +++ b/sdk/tables/aztables/tableClient.go @@ -5,35 +5,51 @@ package aztables import ( "context" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/internal/runtime" ) // A TableClient represents a URL to an Azure Storage blob; the blob may be a block blob, append blob, or page blob. type TableClient struct { - client *tableClient - cred SharedKeyCredential + client *tableClient + service *TableServiceClient + cred SharedKeyCredential + name string } // NewTableClient creates a TableClient object using the specified URL and request policy pipeline. -func NewTableClient(serviceURL string, cred azcore.Credential, options *TableClientOptions) (*TableClient, error) { - con := newConnection(serviceURL, cred, options.getConnectionOptions()) +func NewTableClient(tableName string, serviceURL string, cred azcore.Credential, options *TableClientOptions) (*TableClient, error) { + s, err := NewTableServiceClient(serviceURL, cred, options) + return s.GetTableClient(tableName), err +} - c, _ := cred.(*SharedKeyCredential) +func (t *TableClient) Name() string { + return t.name +} - return &TableClient{client: &tableClient{con}, cred: *c}, nil +// Creates the table with the name specified in NewTableClient +func (t *TableClient) Create(ctx context.Context) (*TableResponseResponse, *runtime.ResponseError) { + return t.service.Create(ctx, t.name) } -// Create -func (t TableClient) Create(ctx context.Context, name string) (TableResponseResponse, error) { - resp, err := t.client.Create(ctx, TableProperties{&name}, nil, nil) - if resp == nil { - return TableResponseResponse{}, err - } else { - return resp.(TableResponseResponse), err - } +// Deletes the current table +func (t *TableClient) Delete(ctx context.Context) (*TableDeleteResponse, *runtime.ResponseError) { + return t.service.Delete(ctx, t.name) } -// Delete -func (t TableClient) Delete(ctx context.Context, name string) (TableDeleteResponse, error) { - return t.client.Delete(ctx, name, nil) +// Queries the tables using the specified QueryOptions +func (t *TableClient) Query(queryOptions QueryOptions) TableEntityQueryResponsePager { + return &tableEntityQueryResponsePager{tableClient: t, queryOptions: &queryOptions, tableQueryOptions: &TableQueryEntitiesOptions{}} +} + +// Creates an entity +func (t *TableClient) AddEntity(ctx context.Context, entity *map[string]interface{}) (*TableInsertEntityResponse, *runtime.ResponseError) { + resp, err := t.client.InsertEntity(ctx, t.name, &TableInsertEntityOptions{TableEntityProperties: entity, ResponsePreference: ResponseFormatReturnNoContent.ToPtr()}, &QueryOptions{}) + if err == nil { + insertResp := resp.(TableInsertEntityResponse) + return &insertResp, nil + } else { + return nil, convertErr(err) + } } diff --git a/sdk/tables/aztables/tableClient_test.go b/sdk/tables/aztables/tableClient_test.go index 0b76e48fd15d..6e2376db00b6 100644 --- a/sdk/tables/aztables/tableClient_test.go +++ b/sdk/tables/aztables/tableClient_test.go @@ -4,9 +4,115 @@ package aztables import ( - chk "gopkg.in/check.v1" // go get gopkg.in/check.v1 + "net/http" + "testing" + + "github.com/Azure/azure-sdk-for-go/sdk/internal/testframework" + chk "gopkg.in/check.v1" ) -func (s *aztestsSuite) TestContainerCreateAccessContainer(c *chk.C) { - // TODO +type tableClientLiveTests struct { + endpointType EndpointType + mode testframework.RecordMode +} + +// Hookup to the testing framework +func Test(t *testing.T) { chk.TestingT(t) } + +// wire up chk to testing +var _ = chk.Suite(&tableClientLiveTests{endpointType: StorageEndpoint, mode: testframework.Playback /* change to Record to re-record tests */}) +var _ = chk.Suite(&tableClientLiveTests{endpointType: CosmosEndpoint, mode: testframework.Playback /* change to Record to re-record tests */}) + +func (s *tableClientLiveTests) TestServiceErrors(c *chk.C) { + client, delete := s.init(c, true) + defer delete() + + // Create a duplicate table to produce an error + _, err := client.Create(ctx) + c.Assert(err.RawResponse().StatusCode, chk.Equals, http.StatusConflict) +} + +func (s *tableClientLiveTests) TestCreateTable(c *chk.C) { + client, delete := s.init(c, false) + defer delete() + + resp, err := client.Create(ctx) + + c.Assert(err, chk.IsNil) + c.Assert(*resp.TableResponse.TableName, chk.Equals, client.Name()) +} + +func (s *tableClientLiveTests) TestAddEntity(c *chk.C) { + client, delete := s.init(c, true) + defer delete() + + entitiesToCreate := createSimpleEntities(1, "partition") + + for _, e := range *entitiesToCreate { + _, err := client.AddEntity(ctx, &e) + c.Assert(err, chk.IsNil) + } +} + +func (s *tableClientLiveTests) TestQuerySimpleEntity(c *chk.C) { + client, delete := s.init(c, true) + defer delete() + + // Add 5 entities + entitiesToCreate := createSimpleEntities(5, "partition") + for _, e := range *entitiesToCreate { + _, err := client.AddEntity(ctx, &e) + c.Assert(err, chk.IsNil) + } + + filter := "RowKey lt '5'" + expectedCount := 4 + var resp TableEntityQueryResponseResponse + pager := client.Query(QueryOptions{Filter: &filter}) + for pager.NextPage(ctx) { + resp = pager.PageResponse() + c.Assert(len(*resp.TableEntityQueryResponse.Value), chk.Equals, expectedCount) + } + resp = pager.PageResponse() + c.Assert(pager.Err(), chk.IsNil) + for _, e := range *resp.TableEntityQueryResponse.Value { + _, ok := e[PartitionKey].(string) + c.Assert(ok, chk.Equals, true) + _, ok = e[RowKey].(string) + c.Assert(ok, chk.Equals, true) + _, ok = e[Timestamp].(string) + c.Assert(ok, chk.Equals, true) + _, ok = e[EtagOdata].(string) + c.Assert(ok, chk.Equals, true) + _, ok = e["StringProp"].(string) + c.Assert(ok, chk.Equals, true) + //TODO: fix when serialization is implemented + _, ok = e["IntProp"].(float64) + c.Assert(ok, chk.Equals, true) + _, ok = e["BoolProp"].(bool) + c.Assert(ok, chk.Equals, true) + } +} + +func (s *tableClientLiveTests) SetUpTest(c *chk.C) { + // setup the test environment + recordedTestSetup(c, testKey(c, s.endpointType), s.endpointType, s.mode) +} + +func (s *tableClientLiveTests) TearDownTest(c *chk.C) { + // teardown the test context + recordedTestTeardown(testKey(c, s.endpointType)) +} + +func (s *tableClientLiveTests) init(c *chk.C, doCreate bool) (*TableClient, func()) { + context := getTestContext(testKey(c, s.endpointType)) + tableName := getTableName(context) + client := context.client.GetTableClient(tableName) + if doCreate { + _, err := client.Create(ctx) + c.Assert(err, chk.IsNil) + } + return client, func() { + client.Delete(ctx) + } } diff --git a/sdk/tables/aztables/tableServiceClient.go b/sdk/tables/aztables/tableServiceClient.go new file mode 100644 index 000000000000..7c9fef74d621 --- /dev/null +++ b/sdk/tables/aztables/tableServiceClient.go @@ -0,0 +1,62 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package aztables + +import ( + "context" + "errors" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/internal/runtime" +) + +// A TableServiceClient represents a URL to an Azure Storage blob; the blob may be a block blob, append blob, or page blob. +type TableServiceClient struct { + client *tableClient + service *serviceClient + cred SharedKeyCredential +} + +// NewTableServiceClient creates a TableClient object using the specified URL and request policy pipeline. +func NewTableServiceClient(serviceURL string, cred azcore.Credential, options *TableClientOptions) (*TableServiceClient, error) { + con := newConnection(serviceURL, cred, options.getConnectionOptions()) + c, _ := cred.(*SharedKeyCredential) + return &TableServiceClient{client: &tableClient{con}, service: &serviceClient{con}, cred: *c}, nil +} + +// Gets a TableClient affinitzed to the specified table name and initialized with the same serviceURL and credentials as this TableServiceClient +func (t *TableServiceClient) GetTableClient(tableName string) *TableClient { + return &TableClient{client: t.client, cred: t.cred, name: tableName, service: t} +} + +// Creates a table with the specified name +func (t *TableServiceClient) Create(ctx context.Context, name string) (*TableResponseResponse, *runtime.ResponseError) { + var r *TableResponseResponse = nil + resp, err := t.client.Create(ctx, TableProperties{&name}, new(TableCreateOptions), new(QueryOptions)) + if err == nil { + tableResp := resp.(TableResponseResponse) + r = &tableResp + } + return r, convertErr(err) +} + +// Deletes a table by name +func (t *TableServiceClient) Delete(ctx context.Context, name string) (*TableDeleteResponse, *runtime.ResponseError) { + resp, err := t.client.Delete(ctx, name, nil) + return &resp, convertErr(err) +} + +// Queries the tables using the specified QueryOptions +func (t *TableServiceClient) QueryTables(queryOptions QueryOptions) TableQueryResponsePager { + return &tableQueryResponsePager{client: t.client, queryOptions: &queryOptions, tableQueryOptions: new(TableQueryOptions)} +} + +func convertErr(err error) *runtime.ResponseError { + var e *runtime.ResponseError + if err == nil || !errors.As(err, &e) { + return nil + } else { + return e + } +} diff --git a/sdk/tables/aztables/tableServiceClient_test.go b/sdk/tables/aztables/tableServiceClient_test.go new file mode 100644 index 000000000000..d0cbf39c070b --- /dev/null +++ b/sdk/tables/aztables/tableServiceClient_test.go @@ -0,0 +1,104 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package aztables + +import ( + "fmt" + "net/http" + + "github.com/Azure/azure-sdk-for-go/sdk/internal/testframework" + chk "gopkg.in/check.v1" +) + +type tableServiceClientLiveTests struct { + endpointType EndpointType + mode testframework.RecordMode +} + +// Hookup to the testing framework +var _ = chk.Suite(&tableServiceClientLiveTests{endpointType: StorageEndpoint, mode: testframework.Playback /* change to Record to re-record tests */}) +var _ = chk.Suite(&tableServiceClientLiveTests{endpointType: CosmosEndpoint, mode: testframework.Playback /* change to Record to re-record tests */}) + +func (s *tableServiceClientLiveTests) TestServiceErrors(c *chk.C) { + context := getTestContext(testKey(c, s.endpointType)) + tableName := getTableName(context) + + _, err := context.client.Create(ctx, tableName) + defer context.client.Delete(ctx, tableName) + c.Assert(err, chk.IsNil) + + // Create a duplicate table to produce an error + _, err = context.client.Create(ctx, tableName) + c.Assert(err.RawResponse().StatusCode, chk.Equals, http.StatusConflict) +} + +func (s *tableServiceClientLiveTests) TestCreateTable(c *chk.C) { + context := getTestContext(testKey(c, s.endpointType)) + tableName := getTableName(context) + + resp, err := context.client.Create(ctx, tableName) + defer context.client.Delete(ctx, tableName) + + c.Assert(err, chk.IsNil) + c.Assert(*resp.TableResponse.TableName, chk.Equals, tableName) +} + +func (s *tableServiceClientLiveTests) TestQueryTable(c *chk.C) { + context := getTestContext(testKey(c, s.endpointType)) + tableCount := 5 + tableNames := make([]string, tableCount) + prefix1 := "zzza" + prefix2 := "zzzb" + + defer cleanupTables(context, &tableNames) + //create 10 tables with our exected prefix and 1 with a different prefix + for i := 0; i < tableCount; i++ { + if i < (tableCount - 1) { + tableNames[i] = getTableName(context, prefix1) + } else { + tableNames[i] = getTableName(context, prefix2) + } + _, err := context.client.Create(ctx, tableNames[i]) + c.Assert(err, chk.IsNil) + } + + // Query for tables with no pagination. The filter should exclude one table from the results + filter := fmt.Sprintf("TableName ge '%s' and TableName lt '%s'", prefix1, prefix2) + pager := context.client.QueryTables(QueryOptions{Filter: &filter}) + + resultCount := 0 + for pager.NextPage(ctx) { + resp := pager.PageResponse() + resultCount += len(*resp.TableQueryResponse.Value) + } + + c.Assert(pager.Err(), chk.IsNil) + c.Assert(resultCount, chk.Equals, tableCount-1) + + // Query for tables with pagination + top := int32(2) + pager = context.client.QueryTables(QueryOptions{Filter: &filter, Top: &top}) + + resultCount = 0 + pageCount := 0 + for pager.NextPage(ctx) { + resp := pager.PageResponse() + resultCount += len(*resp.TableQueryResponse.Value) + pageCount++ + } + + c.Assert(pager.Err(), chk.IsNil) + c.Assert(resultCount, chk.Equals, tableCount-1) + c.Assert(pageCount, chk.Equals, int(top)) +} + +func (s *tableServiceClientLiveTests) SetUpTest(c *chk.C) { + // setup the test environment + recordedTestSetup(c, testKey(c, s.endpointType), s.endpointType, s.mode) +} + +func (s *tableServiceClientLiveTests) TearDownTest(c *chk.C) { + // teardown the test context + recordedTestTeardown(testKey(c, s.endpointType)) +} diff --git a/sdk/tables/aztables/zc_client_options.go b/sdk/tables/aztables/zc_client_options.go index cf24278fd2d2..f0a7200fd141 100644 --- a/sdk/tables/aztables/zc_client_options.go +++ b/sdk/tables/aztables/zc_client_options.go @@ -23,7 +23,7 @@ func (o *TableClientOptions) getConnectionOptions() *connectionOptions { return &connectionOptions{ HTTPClient: o.HTTPClient, - Retry: o.Retry, - Telemetry: o.Telemetry, + Retry: o.Retry, + Telemetry: o.Telemetry, } -} \ No newline at end of file +} diff --git a/sdk/tables/aztables/zc_tableConstants.go b/sdk/tables/aztables/zc_tableConstants.go new file mode 100644 index 000000000000..00e6885a30cb --- /dev/null +++ b/sdk/tables/aztables/zc_tableConstants.go @@ -0,0 +1,22 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package aztables + +const ( + Timestamp = "Timestamp" + PartitionKey = "PartitionKey" + RowKey = "RowKey" + EtagOdata = "odata.etag" + ETag = "ETag" + OdataMetadata = "odata.metadata" + OdataType = "@odata.type" + EdmBinary = "Edm.Binary" + EdmBoolean = "Emd.Boolean" + EdmDateTime = "Edm.DateTime" + EdmDouble = "Edm.Double" + EdmGuid = "Edm.Guid" + EdmInt32 = "Edm.Int32" + EdmInt64 = "Edm.Int64" + Edm = "Edm.String" +) diff --git a/sdk/tables/aztables/zc_table_pagers.go b/sdk/tables/aztables/zc_table_pagers.go new file mode 100644 index 000000000000..73c5bbbd5bfb --- /dev/null +++ b/sdk/tables/aztables/zc_table_pagers.go @@ -0,0 +1,127 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package aztables + +import ( + "context" +) + +// Pager for Table entity queries +type TableEntityQueryResponsePager interface { + // NextPage returns true if the pager advanced to the next page. + // Returns false if there are no more pages or an error occurred. + NextPage(context.Context) bool + + // Page returns the current TableQueryResponseResponse. + PageResponse() TableEntityQueryResponseResponse + + // Err returns the last error encountered while paging. + Err() error +} + +type tableEntityQueryResponsePager struct { + tableClient *TableClient + current *TableEntityQueryResponseResponse + tableQueryOptions *TableQueryEntitiesOptions + queryOptions *QueryOptions + err error +} + +func (p *tableEntityQueryResponsePager) NextPage(ctx context.Context) bool { + if p.err != nil || (p.current != nil && p.current.XMSContinuationNextPartitionKey == nil && p.current.XMSContinuationNextRowKey == nil) { + return false + } + var resp TableEntityQueryResponseResponse + resp, p.err = p.tableClient.client.QueryEntities(ctx, p.tableClient.name, p.tableQueryOptions, p.queryOptions) + p.current = &resp + p.tableQueryOptions.NextPartitionKey = resp.XMSContinuationNextPartitionKey + p.tableQueryOptions.NextRowKey = resp.XMSContinuationNextRowKey + return p.err == nil && resp.TableEntityQueryResponse.Value != nil && len(*resp.TableEntityQueryResponse.Value) > 0 +} + +func (p *tableEntityQueryResponsePager) PageResponse() TableEntityQueryResponseResponse { + return *p.current +} + +func (p *tableEntityQueryResponsePager) Err() error { + return p.err +} + +// Pager for Table Queries +type TableQueryResponsePager interface { + // NextPage returns true if the pager advanced to the next page. + // Returns false if there are no more pages or an error occurred. + NextPage(context.Context) bool + + // Page returns the current TableQueryResponseResponse. + PageResponse() TableQueryResponseResponse + + // Err returns the last error encountered while paging. + Err() error +} + +type tableQueryResponsePager struct { + client *tableClient + current *TableQueryResponseResponse + tableQueryOptions *TableQueryOptions + queryOptions *QueryOptions + err error +} + +func (p *tableQueryResponsePager) NextPage(ctx context.Context) bool { + if p.err != nil || (p.current != nil && p.current.XMSContinuationNextTableName == nil) { + return false + } + var resp TableQueryResponseResponse + resp, p.err = p.client.Query(ctx, p.tableQueryOptions, p.queryOptions) + p.current = &resp + p.tableQueryOptions.NextTableName = resp.XMSContinuationNextTableName + return p.err == nil && resp.TableQueryResponse.Value != nil && len(*resp.TableQueryResponse.Value) > 0 +} + +func (p *tableQueryResponsePager) PageResponse() TableQueryResponseResponse { + return *p.current +} + +func (p *tableQueryResponsePager) Err() error { + return p.err +} + +func castAndRemoveAnnotationsSlice(entities *[]map[string]interface{}) { + +} + +func castAndRemoveAnnotations(entity *map[string]interface{}) { + /* + foreach (var propertyName in entity.Keys) + { + var spanPropertyName = propertyName.AsSpan(); + var iSuffix = spanPropertyName.IndexOf(spanOdataSuffix); + if (iSuffix > 0) + { + // This property is an Odata annotation. Save it in the typeAnnoations dictionary. + typeAnnotationsWithKeys[spanPropertyName.Slice(0, iSuffix).ToString()] = ((entity[propertyName] as string)!, propertyName); + } + } + + // Iterate through the types that are serialized as string by default and Parse them as the correct type, as indicated by the type annotations. + foreach (var annotation in typeAnnotationsWithKeys.Keys) + { + entity[annotation] = typeAnnotationsWithKeys[annotation].TypeAnnotation switch + { + TableConstants.Odata.EdmBinary => Convert.FromBase64String(entity[annotation] as string), + TableConstants.Odata.EdmDateTime => DateTimeOffset.Parse(entity[annotation] as string, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind), + TableConstants.Odata.EdmGuid => Guid.Parse(entity[annotation] as string), + TableConstants.Odata.EdmInt64 => long.Parse(entity[annotation] as string, CultureInfo.InvariantCulture), + _ => throw new NotSupportedException("Not supported type " + typeAnnotationsWithKeys[annotation]) + }; + + // Remove the type annotation property from the dictionary. + entity.Remove(typeAnnotationsWithKeys[annotation].AnnotationKey); + } + */ + // for name, val := range *entity { + + // } +} diff --git a/sdk/tables/aztables/zt_tableRecordedTests.go b/sdk/tables/aztables/zt_tableRecordedTests.go new file mode 100644 index 000000000000..af530b241351 --- /dev/null +++ b/sdk/tables/aztables/zt_tableRecordedTests.go @@ -0,0 +1,132 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package aztables + +import ( + "context" + "fmt" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/internal/testframework" + + chk "gopkg.in/check.v1" +) + +type tablesRecordedTests struct{} + +type testContext struct { + recording *testframework.Recording + client *TableServiceClient +} + +const ( + storageAccountNameEnvVar = "TABLES_STORAGE_ACCOUNT_NAME" + cosmosAccountNameEnnVar = "TABLES_COSMOS_ACCOUNT_NAME" + storageEndpointSuffixEnvVar = "STORAGE_ENDPOINT_SUFFIX" + cosmosEndpointSuffixEnvVar = "COSMOS_TABLES_ENDPOINT_SUFFIX" + storageAccountKeyEnvVar = "TABLES_PRIMARY_STORAGE_ACCOUNT_KEY" + cosmosAccountKeyEnvVar = "TABLES_PRIMARY_COSMOS_ACCOUNT_KEY" + tableNamePrefix = "gotable" + DefaultStorageSuffix = "core.windows.net" + DefaultCosmosSuffix = "cosmos.azure.com" +) + +type EndpointType string + +const ( + StorageEndpoint EndpointType = "storage" + CosmosEndpoint EndpointType = "cosmos" +) + +var ctx = context.Background() +var clientsMap map[string]*testContext = make(map[string]*testContext) + +func storageURI(accountName string, endpointSuffix string) string { + return "https://" + accountName + ".table." + endpointSuffix +} + +func cosmosURI(accountName string, endpointSuffix string) string { + return "https://" + accountName + ".table." + endpointSuffix +} + +// create the test specific TableClient and wire it up to recordings +func recordedTestSetup(c *chk.C, testName string, endpointType EndpointType, mode testframework.RecordMode) { + var accountName string + var suffix string + var cred *SharedKeyCredential + var uri string + + // init the test framework + recording, err := testframework.NewRecording(c, mode, string(endpointType)) + c.Assert(err, chk.IsNil) + + if endpointType == StorageEndpoint { + accountName = recording.GetRecordedVariable(storageAccountNameEnvVar) + suffix = recording.GetOptionalRecordedVariable(storageEndpointSuffixEnvVar, DefaultStorageSuffix) + cred, _ = NewSharedKeyCredential(accountName, recording.GetRecordedVariable(storageAccountKeyEnvVar, testframework.Secret_Base64String)) + uri = storageURI(accountName, suffix) + } else { + accountName = recording.GetRecordedVariable(cosmosAccountNameEnnVar) + suffix = recording.GetOptionalRecordedVariable(cosmosEndpointSuffixEnvVar, DefaultCosmosSuffix) + cred, _ = NewSharedKeyCredential(accountName, recording.GetRecordedVariable(cosmosAccountKeyEnvVar, testframework.Secret_Base64String)) + uri = cosmosURI(accountName, suffix) + } + + client, err := NewTableServiceClient(uri, cred, &TableClientOptions{HTTPClient: recording, Retry: azcore.RetryOptions{MaxRetries: -1}}) + c.Assert(err, chk.IsNil) + clientsMap[testName] = &testContext{client: client, recording: recording} +} + +func recordedTestTeardown(key string) { + clientsMap[key].recording.Stop() +} + +// cleans up the specified tables. If tables is nil, all tables will be deleted +func cleanupTables(context *testContext, tables *[]string) { + c := context.client + if tables == nil { + pager := c.QueryTables(QueryOptions{}) + for pager.NextPage(ctx) { + for _, t := range *(pager.PageResponse().TableQueryResponse.Value) { + c.Delete(ctx, *t.TableName) + } + } + } else { + for _, t := range *tables { + c.Delete(ctx, t) + } + } +} + +func getTestContext(key string) *testContext { + return clientsMap[key] +} + +func getTableName(context *testContext, prefix ...string) string { + if len(prefix) == 0 { + return context.recording.GenerateAlphaNumericId(tableNamePrefix, 20, true) + } else { + return context.recording.GenerateAlphaNumericId(prefix[0], 20, true) + } +} + +func testKey(c *chk.C, ep EndpointType) string { + return c.TestName() + string(ep) +} + +func createSimpleEntities(count int, pk string) *[]map[string]interface{} { + result := make([]map[string]interface{}, count) + + for i := 1; i <= count; i++ { + var e = map[string]interface{}{ + PartitionKey: pk, + RowKey: fmt.Sprint(i), + "StringProp": fmt.Sprintf("some string %d", i), + "IntProp": i, + "BoolProp": true, + } + result[i-1] = e + } + return &result +} diff --git a/sdk/tables/aztables/zt_test.go b/sdk/tables/aztables/zt_test.go index c9e649bca203..6403418e6885 100644 --- a/sdk/tables/aztables/zt_test.go +++ b/sdk/tables/aztables/zt_test.go @@ -97,7 +97,7 @@ func cosmosEndpointSuffix() string { } } -func createTableClient(endpointType EndpointType) (*TableClient, error) { +func createTableClient(endpointType EndpointType) (TableClient, error) { if endpointType == StorageEndpoint { storageCred, _ := NewSharedKeyCredential(storageAccountName(), storageAccountKey()) return NewTableClient(storageURI(), storageCred, nil) diff --git a/sdk/tables/aztables/zz_generated_connection.go b/sdk/tables/aztables/zz_generated_connection.go index 990122c2b6e3..325fa053b1bd 100644 --- a/sdk/tables/aztables/zz_generated_connection.go +++ b/sdk/tables/aztables/zz_generated_connection.go @@ -14,6 +14,7 @@ import ( const scope = "foo" const telemetryInfo = "azsdk-go-tables/" + // connectionOptions contains configuration settings for the connection's pipeline. // All zero-value fields will be initialized with their default values. type connectionOptions struct { @@ -67,7 +68,6 @@ func (c *connection) Endpoint() string { } // Pipeline returns the connection's pipeline. -func (c *connection) Pipeline() (azcore.Pipeline) { +func (c *connection) Pipeline() azcore.Pipeline { return c.p } - From e58dbc15425100c5a74bbec622bfa1211f6d723c Mon Sep 17 00:00:00 2001 From: Christopher Scott Date: Mon, 5 Apr 2021 18:00:21 -0500 Subject: [PATCH 02/18] fixups --- sdk/tables/aztables/go.mod | 3 +- sdk/tables/aztables/zt_test.go | 123 --------------------------------- 2 files changed, 2 insertions(+), 124 deletions(-) delete mode 100644 sdk/tables/aztables/zt_test.go diff --git a/sdk/tables/aztables/go.mod b/sdk/tables/aztables/go.mod index c557e375933e..7c7e16da9401 100644 --- a/sdk/tables/aztables/go.mod +++ b/sdk/tables/aztables/go.mod @@ -5,6 +5,7 @@ go 1.13 replace github.com/Azure/azure-sdk-for-go/sdk/internal => ../../internal require ( - github.com/Azure/azure-sdk-for-go/sdk/azcore v0.14.1 + github.com/Azure/azure-sdk-for-go/sdk/azcore v0.14.2 + github.com/Azure/azure-sdk-for-go/sdk/internal v0.5.0 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c ) diff --git a/sdk/tables/aztables/zt_test.go b/sdk/tables/aztables/zt_test.go deleted file mode 100644 index 6403418e6885..000000000000 --- a/sdk/tables/aztables/zt_test.go +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -package aztables - -import ( - "context" - "errors" - "fmt" - "os" - "testing" - "time" - - chk "gopkg.in/check.v1" -) - -// For testing docs, see: https://labix.org/gocheck -// To test a specific test: go test -check.f MyTestSuite - -// Hookup to the testing framework -func Test(t *testing.T) { chk.TestingT(t) } - -type aztestsSuite struct{} - -var _ = chk.Suite(&aztestsSuite{}) - -const ( - storageAccountNameEnvVar = "TABLES_STORAGE_ACCOUNT_NAME" - cosmosAccountNameEnnVar = "TABLES_COSMOS_ACCOUNT_NAME" - accountKeyEnvVar = "TABLES_PRIMARY_STORAGE_ACCOUNT_KEY" - storageEndpointSuffixEnvVar = "STORAGE_ENDPOINT_SUFFIX" - cosmosEndpointSuffixEnvVar = "COSMOS_TABLES_ENDPOINT_SUFFIX" - storageAccountKeyEnvVar = "TABLES_PRIMARY_STORAGE_ACCOUNT_KEY" - cosmosAccountKeyEnvVar = "TABLES_PRIMARY_COSMOS_ACCOUNT_KEY" - tableNamePrefix = "gotable" - DefaultStorageSuffix = "core.windows.net" - DefaultCosmosSuffix = "cosmos.azure.com" -) - -type EndpointType string - -const ( - StorageEndpoint EndpointType = "storage" - CosmosEndpoint EndpointType = "cosmos" -) - -var ctx = context.Background() - -func getRequiredEnv(name string) string { - env, ok := os.LookupEnv(name) - if ok { - return env - } else { - panic("Required environment variable not set: " + name) - } -} - -func storageURI() string { - return "https://" + storageAccountName() + ".table." + storageEndpointSuffix() -} - -func cosmosURI() string { - return "https://" + cosmosAccountName() + ".table" + cosmosAccountName() -} - -func storageAccountName() string { - return getRequiredEnv(storageAccountNameEnvVar) -} - -func cosmosAccountName() string { - return getRequiredEnv(cosmosAccountNameEnnVar) -} - -func cosmosAccountKey() string { - return getRequiredEnv(cosmosAccountKeyEnvVar) -} - -func storageAccountKey() string { - return getRequiredEnv(storageAccountKeyEnvVar) -} - -func storageEndpointSuffix() string { - suffix, ok := os.LookupEnv(storageEndpointSuffixEnvVar) - if ok { - return suffix - } else { - return DefaultStorageSuffix - } -} - -func cosmosEndpointSuffix() string { - suffix, ok := os.LookupEnv(cosmosEndpointSuffix()) - if ok { - return suffix - } else { - return DefaultCosmosSuffix - } -} - -func createTableClient(endpointType EndpointType) (TableClient, error) { - if endpointType == StorageEndpoint { - storageCred, _ := NewSharedKeyCredential(storageAccountName(), storageAccountKey()) - return NewTableClient(storageURI(), storageCred, nil) - } else { - cosmosCred, _ := NewSharedKeyCredential(cosmosAccountName(), cosmosAccountKey()) - return NewTableClient(cosmosURI(), cosmosCred, nil) - } -} - -func getGenericCredential(accountType string) (*SharedKeyCredential, error) { - - accountName, accountKey := getRequiredEnv(storageAccountNameEnvVar), getRequiredEnv(accountKeyEnvVar) - if accountName == "" || accountKey == "" { - return nil, errors.New(storageAccountNameEnvVar + " and/or " + accountKeyEnvVar + " environment variables not specified.") - } - return NewSharedKeyCredential(accountName, accountKey) -} - -func generateName() string { - currentTime := time.Now() - name := fmt.Sprintf("%s%d%d%d", tableNamePrefix, currentTime.Minute(), currentTime.Second(), currentTime.Nanosecond()) - return name -} From 656c2801da673692b55627181ef17cb1cd8d7b47 Mon Sep 17 00:00:00 2001 From: Christopher Scott Date: Tue, 6 Apr 2021 09:58:05 -0500 Subject: [PATCH 03/18] eliminate dependency on go-check --- sdk/internal/testframework/recording.go | 27 +++++++------ sdk/internal/testframework/recording_test.go | 32 +++++++++------ sdk/internal/testframework/request_matcher.go | 22 +++++------ .../testframework/request_matcher_test.go | 30 ++++++++------ sdk/internal/testframework/testcontext.go | 39 +++++++++++++++++++ sdk/tables/aztables/zt_tableRecordedTests.go | 3 +- 6 files changed, 106 insertions(+), 47 deletions(-) create mode 100644 sdk/internal/testframework/testcontext.go diff --git a/sdk/internal/testframework/recording.go b/sdk/internal/testframework/recording.go index bb53ed1796b7..8fc89dacc7fa 100644 --- a/sdk/internal/testframework/recording.go +++ b/sdk/internal/testframework/recording.go @@ -19,7 +19,6 @@ import ( "github.com/dnaeon/go-vcr/cassette" "github.com/dnaeon/go-vcr/recorder" - chk "gopkg.in/check.v1" "gopkg.in/yaml.v2" ) @@ -33,7 +32,7 @@ type Recording struct { recorder *recorder.Recorder src rand.Source sanitizer *RecordingSanitizer - c *chk.C + c TestContext } const ( @@ -66,9 +65,9 @@ const ( Secret_Base64String VariableType = "secret_base64String" ) -func NewRecording(c *chk.C, mode RecordMode, testSuffixes ...string) (*Recording, error) { +func NewRecording(c TestContext, mode RecordMode, testSuffixes ...string) (*Recording, error) { // create recorder based on the test name, recordMode, variables, and sanitizers - recPath, varPath := getFilePaths(c, testSuffixes) + recPath, varPath := getFilePaths(c.Name(), testSuffixes) rec, err := recorder.NewAsMode(recPath, modeMap[mode], nil) if err != nil { @@ -89,7 +88,8 @@ func NewRecording(c *chk.C, mode RecordMode, testSuffixes ...string) (*Recording variables: make(map[string]string), previousSessionVariables: make(map[string]string), recorder: rec, - c: c} + c: c, + } // Try loading the recording if it already exists to hydrate the variables err = recording.initVariables() @@ -133,10 +133,7 @@ func (r *Recording) Do(req *http.Request) (*http.Response, error) { resp, err := r.recorder.RoundTrip(req) if err == cassette.ErrInteractionNotFound { error := missingRequestError(req) - r.c.Log(error) - r.c.Fail() - // TODO: remove this if https://github.com/go-check/check/pull/127 merges - panic(error) + r.c.Fail(error) } return resp, err } @@ -304,13 +301,19 @@ func (r *Recording) initRandomSource() { } // returns (recordingFilePath, variablesFilePath) -func getFilePaths(c *chk.C, suffixes []string) (string, string) { - testName := strings.Split(c.TestName(), ".") +func getFilePaths(name string, suffixes []string) (string, string) { + testName := strings.SplitN(name, ".", 2) var suffix string = "" if len(suffixes) > 0 { suffix = "(" + strings.Join(suffixes, ",") + ")" } - recPath := "recordings/" + testName[0] + suffix + "/" + testName[1] + var recPath string + if len(testName) == 2 { + + recPath = "recordings/" + testName[0] + suffix + "/" + testName[1] + } else { + recPath = "recordings/" + name + } varPath := fmt.Sprintf("%s-variables.yaml", recPath) return recPath, varPath } diff --git a/sdk/internal/testframework/recording_test.go b/sdk/internal/testframework/recording_test.go index 507024c27d45..8f38b2d85fb6 100644 --- a/sdk/internal/testframework/recording_test.go +++ b/sdk/internal/testframework/recording_test.go @@ -22,10 +22,11 @@ type recordingTests struct{} var _ = chk.Suite(&recordingTests{}) func (r *recordingTests) Test_InitializeRecording(c *chk.C) { + context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) expectedMode := Playback - target, err := NewRecording(c, expectedMode) + target, err := NewRecording(context, expectedMode) c.Assert(err, chk.IsNil) c.Assert(target.RecordingFile, chk.NotNil) c.Assert(target.VariablesFile, chk.NotNil) @@ -36,8 +37,9 @@ func (r *recordingTests) Test_InitializeRecording(c *chk.C) { } func (r *recordingTests) Test_StopDoesNotSaveVariablesWhenNoVariablesExist(c *chk.C) { + context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) - target, err := NewRecording(c, Playback) + target, err := NewRecording(context, Playback) c.Assert(err, chk.IsNil) err = target.Stop() @@ -48,12 +50,13 @@ func (r *recordingTests) Test_StopDoesNotSaveVariablesWhenNoVariablesExist(c *ch } func (r *recordingTests) Test_RecordedVariables(c *chk.C) { + context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) nonExistingEnvVar := "nonExistingEnvVar" expectedVariableValue := "foobar" variablesMap := map[string]string{} - target, err := NewRecording(c, Playback) + target, err := NewRecording(context, Playback) c.Assert(err, chk.IsNil) // optional variables always succeed. @@ -78,6 +81,7 @@ func (r *recordingTests) Test_RecordedVariables(c *chk.C) { } func (r *recordingTests) Test_RecordedVariablesSanitized(c *chk.C) { + context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) SanitizedStringVar := "sanitizedvar" SanitizedBase64StrigVar := "sanitizedbase64var" @@ -85,7 +89,7 @@ func (r *recordingTests) Test_RecordedVariablesSanitized(c *chk.C) { secretBase64 := "asdfasdf==" variablesMap := map[string]string{} - target, err := NewRecording(c, Playback) + target, err := NewRecording(context, Playback) c.Assert(err, chk.IsNil) // call GetOptionalRecordedVariable with the Secret_String VariableType arg @@ -113,12 +117,13 @@ func (r *recordingTests) Test_RecordedVariablesSanitized(c *chk.C) { } func (r *recordingTests) Test_StopSavesVariablesIfExistAndReadsPreviousVariables(c *chk.C) { + context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) expectedVariableName := "someVariable" expectedVariableValue := "foobar" variablesMap := map[string]string{} - target, err := NewRecording(c, Playback) + target, err := NewRecording(context, Playback) c.Assert(err, chk.IsNil) target.GetOptionalRecordedVariable(expectedVariableName, expectedVariableValue) @@ -133,7 +138,7 @@ func (r *recordingTests) Test_StopSavesVariablesIfExistAndReadsPreviousVariables c.Assert(actualValue, chk.Equals, expectedVariableValue) variablesMap = map[string]string{} - target2, err := NewRecording(c, Playback) + target2, err := NewRecording(context, Playback) c.Assert(err, chk.IsNil) err = target.Stop() @@ -147,10 +152,11 @@ func (r *recordingTests) Test_StopSavesVariablesIfExistAndReadsPreviousVariables } func (r *recordingTests) Test_GenerateAlphaNumericId(c *chk.C) { + context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) prefix := "myprefix" - target, err := NewRecording(c, Playback) + target, err := NewRecording(context, Playback) c.Assert(err, chk.IsNil) generated1 := target.GenerateAlphaNumericId(prefix, 10, true) @@ -164,7 +170,7 @@ func (r *recordingTests) Test_GenerateAlphaNumericId(c *chk.C) { err = target.Stop() c.Assert(err, chk.IsNil) - target2, err := NewRecording(c, Playback) + target2, err := NewRecording(context, Playback) c.Assert(err, chk.IsNil) generated2 := target2.GenerateAlphaNumericId(prefix, 10, true) @@ -177,12 +183,13 @@ func (r *recordingTests) Test_GenerateAlphaNumericId(c *chk.C) { } func (s *recordingTests) TestRecordRequestsAndDoMatching(c *chk.C) { + context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) server, cleanup := mock.NewServer() server.SetResponse() defer cleanup() rt := NewMockRoundTripper(server) - target, err := NewRecording(c, Playback) + target, err := NewRecording(context, Playback) target.recorder.SetTransport(rt) reqUrl := server.URL() + "/" + target.GenerateAlphaNumericId("", 5, true) @@ -202,7 +209,7 @@ func (s *recordingTests) TestRecordRequestsAndDoMatching(c *chk.C) { } // re-initialize the recording - target, err = NewRecording(c, Playback) + target, err = NewRecording(context, Playback) target.recorder.SetTransport(rt) // re-create the random url using the recorded variables @@ -216,12 +223,13 @@ func (s *recordingTests) TestRecordRequestsAndDoMatching(c *chk.C) { } func (s *recordingTests) TestRecordRequestsAndFailMatchingForMissingRecording(c *chk.C) { + context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) server, cleanup := mock.NewServer() server.SetResponse() defer cleanup() rt := NewMockRoundTripper(server) - target, err := NewRecording(c, Playback) + target, err := NewRecording(context, Playback) target.recorder.SetTransport(rt) reqUrl := server.URL() + "/" + target.GenerateAlphaNumericId("", 5, true) @@ -241,7 +249,7 @@ func (s *recordingTests) TestRecordRequestsAndFailMatchingForMissingRecording(c } // re-initialize the recording - target, err = NewRecording(c, Playback) + target, err = NewRecording(context, Playback) target.recorder.SetTransport(rt) // re-create the random url using the recorded variables diff --git a/sdk/internal/testframework/request_matcher.go b/sdk/internal/testframework/request_matcher.go index 65eee6b68730..c0c633597a5a 100644 --- a/sdk/internal/testframework/request_matcher.go +++ b/sdk/internal/testframework/request_matcher.go @@ -7,12 +7,12 @@ package testframework import ( "bytes" + "fmt" "io/ioutil" "net/http" "reflect" "github.com/dnaeon/go-vcr/cassette" - chk "gopkg.in/check.v1" ) type RequestMatcher struct { @@ -36,7 +36,7 @@ var headerValuesMismatch = "Test recording header '%s' does not match. request: var methodMismatch = "Test recording methods do not match. request: %s, recording: %s" var urlMismatch = "Test recording URLs do not match. request: %s, recording: %s" -func compareBodies(r *http.Request, i cassette.Request, c *chk.C) bool { +func compareBodies(r *http.Request, i cassette.Request, c TestContext) bool { body := bytes.Buffer{} if r.Body != nil { _, err := body.ReadFrom(r.Body) @@ -47,28 +47,28 @@ func compareBodies(r *http.Request, i cassette.Request, c *chk.C) bool { } bodiesMatch := body.String() == i.Body if !bodiesMatch { - c.Logf("Test recording bodies do not match.\nrequest: %s\nrecording: %s", body.String(), i.Body) + c.Log(fmt.Sprintf("Test recording bodies do not match.\nrequest: %s\nrecording: %s", body.String(), i.Body)) } return bodiesMatch } -func compareURLs(r *http.Request, i cassette.Request, c *chk.C) bool { +func compareURLs(r *http.Request, i cassette.Request, c TestContext) bool { if r.URL.String() != i.URL { - c.Logf(urlMismatch, r.URL.String(), i.URL) + c.Log(fmt.Sprintf(urlMismatch, r.URL.String(), i.URL)) return false } return true } -func compareMethods(r *http.Request, i cassette.Request, c *chk.C) bool { +func compareMethods(r *http.Request, i cassette.Request, c TestContext) bool { if r.Method != i.Method { - c.Logf(methodMismatch, r.Method, i.Method) + c.Log(fmt.Sprintf(methodMismatch, r.Method, i.Method)) return false } return true } -func compareHeaders(r *http.Request, i cassette.Request, c *chk.C) bool { +func compareHeaders(r *http.Request, i cassette.Request, c TestContext) bool { unVisitedCassetteKeys := make(map[string]*string, len(i.Headers)) // clone the cassette keys to track which we have seen for k := range i.Headers { @@ -89,20 +89,20 @@ func compareHeaders(r *http.Request, i cassette.Request, c *chk.C) bool { headersMatch := reflect.DeepEqual(requestHeader, recordedHeader) if !headersMatch { // headers don't match - c.Logf(headerValuesMismatch, key, requestHeader, recordedHeader) + c.Log(fmt.Sprintf(headerValuesMismatch, key, requestHeader, recordedHeader)) return false } } else { // header not found - c.Logf(recordingHeaderMissing, key) + c.Log(fmt.Sprintf(recordingHeaderMissing, key)) return false } } if len(unVisitedCassetteKeys) > 0 { // headers exist in the recording that do not exist in the request for headerName := range unVisitedCassetteKeys { - c.Logf(requestHeaderMissing, headerName) + c.Log(fmt.Sprintf(requestHeaderMissing, headerName)) } return false } diff --git a/sdk/internal/testframework/request_matcher_test.go b/sdk/internal/testframework/request_matcher_test.go index 57ebba7eb67c..da9fa41e8f0f 100644 --- a/sdk/internal/testframework/request_matcher_test.go +++ b/sdk/internal/testframework/request_matcher_test.go @@ -28,18 +28,19 @@ const unMatchedBody string = "This body does not match." var _ = chk.Suite(&requestMatcherTests{}) func (s *requestMatcherTests) TestCompareBodies(c *chk.C) { + context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) req := http.Request{Body: closerFromString(matchedBody)} recReq := cassette.Request{Body: matchedBody} - isMatch := compareBodies(&req, recReq, c) + isMatch := compareBodies(&req, recReq, context) c.Assert(isMatch, chk.Equals, true) // make the requests mis-match req.Body = closerFromString((unMatchedBody)) - isMatch = compareBodies(&req, recReq, c) + isMatch = compareBodies(&req, recReq, context) c.Assert(isMatch, chk.Equals, false) log := c.GetTestLog() @@ -47,6 +48,7 @@ func (s *requestMatcherTests) TestCompareBodies(c *chk.C) { } func (s *requestMatcherTests) TestCompareHeadersIgnoresIgnoredHeaders(c *chk.C) { + context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) // populate only ignored headers that do not match reqHeaders := make(http.Header) @@ -59,13 +61,14 @@ func (s *requestMatcherTests) TestCompareHeadersIgnoresIgnoredHeaders(c *chk.C) req := http.Request{Header: reqHeaders} recReq := cassette.Request{Headers: recordedHeaders} - isMatch := compareHeaders(&req, recReq, c) + isMatch := compareHeaders(&req, recReq, context) // All headers match c.Assert(isMatch, chk.Equals, true) } func (s *requestMatcherTests) TestCompareHeadersMatchesHeaders(c *chk.C) { + context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) // populate only ignored headers that do not match reqHeaders := make(http.Header) @@ -80,12 +83,13 @@ func (s *requestMatcherTests) TestCompareHeadersMatchesHeaders(c *chk.C) { recReq := cassette.Request{Headers: recordedHeaders} c.Assert( - compareHeaders(&req, recReq, c), + compareHeaders(&req, recReq, context), chk.Equals, true) } func (s *requestMatcherTests) TestCompareHeadersFailsMissingRecHeader(c *chk.C) { + context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) // populate only ignored headers that do not match reqHeaders := make(http.Header) @@ -104,13 +108,14 @@ func (s *requestMatcherTests) TestCompareHeadersFailsMissingRecHeader(c *chk.C) reqHeaders[header2] = headerValue c.Assert( - compareHeaders(&req, recReq, c), + compareHeaders(&req, recReq, context), chk.Equals, false) c.Assert(c.GetTestLog(), chk.Equals, fmt.Sprintf(recordingHeaderMissing+"\n", header2)) } func (s *requestMatcherTests) TestCompareHeadersFailsMissingReqHeader(c *chk.C) { + context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) // populate only ignored headers that do not match reqHeaders := make(http.Header) @@ -129,13 +134,14 @@ func (s *requestMatcherTests) TestCompareHeadersFailsMissingReqHeader(c *chk.C) recordedHeaders[header2] = headerValue c.Assert( - compareHeaders(&req, recReq, c), + compareHeaders(&req, recReq, context), chk.Equals, false) c.Assert(c.GetTestLog(), chk.Equals, fmt.Sprintf(requestHeaderMissing+"\n", header2)) } func (s *requestMatcherTests) TestCompareHeadersFailsMismatchedValues(c *chk.C) { + context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) // populate only ignored headers that do not match reqHeaders := make(http.Header) @@ -156,27 +162,28 @@ func (s *requestMatcherTests) TestCompareHeadersFailsMismatchedValues(c *chk.C) reqHeaders[header2] = mismatch c.Assert( - compareHeaders(&req, recReq, c), + compareHeaders(&req, recReq, context), chk.Equals, false) c.Assert(c.GetTestLog(), chk.Equals, fmt.Sprintf(headerValuesMismatch+"\n", header2, mismatch, headerValue)) } func (s *requestMatcherTests) TestCompareURLs(c *chk.C) { + context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) scheme := "https" host := "foo.bar" req := http.Request{URL: &url.URL{Scheme: scheme, Host: host}} recReq := cassette.Request{URL: scheme + "://" + host} c.Assert( - compareURLs(&req, recReq, c), + compareURLs(&req, recReq, context), chk.Equals, true) req.URL.Path = "noMatch" c.Assert( - compareURLs(&req, recReq, c), + compareURLs(&req, recReq, context), chk.Equals, false) @@ -184,20 +191,21 @@ func (s *requestMatcherTests) TestCompareURLs(c *chk.C) { } func (s *requestMatcherTests) TestCompareMethods(c *chk.C) { + context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) methodPost := "POST" methodPatch := "PATCH" req := http.Request{Method: methodPost} recReq := cassette.Request{Method: methodPost} c.Assert( - compareMethods(&req, recReq, c), + compareMethods(&req, recReq, context), chk.Equals, true) req.Method = methodPatch c.Assert( - compareMethods(&req, recReq, c), + compareMethods(&req, recReq, context), chk.Equals, false) diff --git a/sdk/internal/testframework/testcontext.go b/sdk/internal/testframework/testcontext.go new file mode 100644 index 000000000000..ab5cd24f1278 --- /dev/null +++ b/sdk/internal/testframework/testcontext.go @@ -0,0 +1,39 @@ +// +build go1.13 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package testframework + +import () + +type TestContext interface { + Fail(string) + Log(string) + Name() string +} + +type testContext struct { + fail Failer + log Logger + name string +} + +type Failer func(string) +type Logger func(string) +type Name func() string + +func NewTestContext(f Failer, l Logger, name Name) TestContext { + return &testContext{fail: f, log: l, name: name()} +} + +func (c *testContext) Fail(msg string) { + c.fail(msg) + panic(msg) +} +func (c *testContext) Log(msg string) { + c.log(msg) +} +func (c *testContext) Name() string { + return c.name +} diff --git a/sdk/tables/aztables/zt_tableRecordedTests.go b/sdk/tables/aztables/zt_tableRecordedTests.go index af530b241351..587e78cb38b5 100644 --- a/sdk/tables/aztables/zt_tableRecordedTests.go +++ b/sdk/tables/aztables/zt_tableRecordedTests.go @@ -58,7 +58,8 @@ func recordedTestSetup(c *chk.C, testName string, endpointType EndpointType, mod var uri string // init the test framework - recording, err := testframework.NewRecording(c, mode, string(endpointType)) + context := testframework.NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) + recording, err := testframework.NewRecording(context, mode, string(endpointType)) c.Assert(err, chk.IsNil) if endpointType == StorageEndpoint { From d74b17c7b4482ab0d4082a6017d382ae75f3aaf3 Mon Sep 17 00:00:00 2001 From: Christopher Scott Date: Tue, 6 Apr 2021 10:11:08 -0500 Subject: [PATCH 04/18] format --- sdk/internal/testframework/testcontext.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/sdk/internal/testframework/testcontext.go b/sdk/internal/testframework/testcontext.go index ab5cd24f1278..028f53fd23c2 100644 --- a/sdk/internal/testframework/testcontext.go +++ b/sdk/internal/testframework/testcontext.go @@ -5,8 +5,6 @@ package testframework -import () - type TestContext interface { Fail(string) Log(string) From e736b00e988b3342f8687ce916095986d2d26342 Mon Sep 17 00:00:00 2001 From: Christopher Scott Date: Tue, 6 Apr 2021 23:50:02 -0500 Subject: [PATCH 05/18] refactor testing to testify --- sdk/internal/testframework/recording.go | 94 ++++++++++--------- sdk/internal/testframework/recording_test.go | 33 ++++--- sdk/internal/testframework/testcontext.go | 5 +- sdk/tables/aztables/go.mod | 2 +- sdk/tables/aztables/go.sum | 9 ++ .../TestCreateTable-variables.yaml | 0 .../TestCreateTable.yaml | 0 .../TestQueryTable-variables.yaml | 0 .../TestQueryTable.yaml | 0 .../TestServiceErrors-variables.yaml | 0 .../TestServiceErrors.yaml | 0 .../TestCreateTable-variables.yaml | 0 .../TestCreateTable.yaml | 0 .../TestQueryTable-variables.yaml | 0 .../TestQueryTable.yaml | 0 .../TestServiceErrors-variables.yaml | 0 .../TestServiceErrors.yaml | 0 .../TestAddEntity-variables.yaml | 0 .../TestAddEntity.yaml | 0 .../TestCreateTable-variables.yaml | 0 .../TestCreateTable.yaml | 0 .../TestQuerySimpleEntity-variables.yaml | 0 .../TestQuerySimpleEntity.yaml | 0 .../TestServiceErrors-variables.yaml | 0 .../TestServiceErrors.yaml | 0 .../TestAddEntity-variables.yaml | 0 .../TestAddEntity.yaml | 0 .../TestCreateTable-variables.yaml | 0 .../TestCreateTable.yaml | 0 .../TestQuerySimpleEntity-variables.yaml | 0 .../TestQuerySimpleEntity.yaml | 0 .../TestServiceErrors-variables.yaml | 0 .../TestServiceErrors.yaml | 0 sdk/tables/aztables/tableClient_test.go | 87 +++++++++-------- .../aztables/tableServiceClient_test.go | 80 +++++++++------- sdk/tables/aztables/zt_tableRecordedTests.go | 43 +++++---- 36 files changed, 200 insertions(+), 153 deletions(-) rename sdk/tables/aztables/recordings/{tableServiceClientLiveTests(cosmos) => TestServiceClient_Cosmos}/TestCreateTable-variables.yaml (100%) rename sdk/tables/aztables/recordings/{tableServiceClientLiveTests(cosmos) => TestServiceClient_Cosmos}/TestCreateTable.yaml (100%) rename sdk/tables/aztables/recordings/{tableServiceClientLiveTests(cosmos) => TestServiceClient_Cosmos}/TestQueryTable-variables.yaml (100%) rename sdk/tables/aztables/recordings/{tableServiceClientLiveTests(cosmos) => TestServiceClient_Cosmos}/TestQueryTable.yaml (100%) rename sdk/tables/aztables/recordings/{tableServiceClientLiveTests(cosmos) => TestServiceClient_Cosmos}/TestServiceErrors-variables.yaml (100%) rename sdk/tables/aztables/recordings/{tableServiceClientLiveTests(cosmos) => TestServiceClient_Cosmos}/TestServiceErrors.yaml (100%) rename sdk/tables/aztables/recordings/{tableServiceClientLiveTests(storage) => TestServiceClient_Storage}/TestCreateTable-variables.yaml (100%) rename sdk/tables/aztables/recordings/{tableServiceClientLiveTests(storage) => TestServiceClient_Storage}/TestCreateTable.yaml (100%) rename sdk/tables/aztables/recordings/{tableServiceClientLiveTests(storage) => TestServiceClient_Storage}/TestQueryTable-variables.yaml (100%) rename sdk/tables/aztables/recordings/{tableServiceClientLiveTests(storage) => TestServiceClient_Storage}/TestQueryTable.yaml (100%) rename sdk/tables/aztables/recordings/{tableServiceClientLiveTests(storage) => TestServiceClient_Storage}/TestServiceErrors-variables.yaml (100%) rename sdk/tables/aztables/recordings/{tableServiceClientLiveTests(storage) => TestServiceClient_Storage}/TestServiceErrors.yaml (100%) rename sdk/tables/aztables/recordings/{tableClientLiveTests(cosmos) => TestTableClient_Cosmos}/TestAddEntity-variables.yaml (100%) rename sdk/tables/aztables/recordings/{tableClientLiveTests(cosmos) => TestTableClient_Cosmos}/TestAddEntity.yaml (100%) rename sdk/tables/aztables/recordings/{tableClientLiveTests(cosmos) => TestTableClient_Cosmos}/TestCreateTable-variables.yaml (100%) rename sdk/tables/aztables/recordings/{tableClientLiveTests(cosmos) => TestTableClient_Cosmos}/TestCreateTable.yaml (100%) rename sdk/tables/aztables/recordings/{tableClientLiveTests(cosmos) => TestTableClient_Cosmos}/TestQuerySimpleEntity-variables.yaml (100%) rename sdk/tables/aztables/recordings/{tableClientLiveTests(cosmos) => TestTableClient_Cosmos}/TestQuerySimpleEntity.yaml (100%) rename sdk/tables/aztables/recordings/{tableClientLiveTests(cosmos) => TestTableClient_Cosmos}/TestServiceErrors-variables.yaml (100%) rename sdk/tables/aztables/recordings/{tableClientLiveTests(cosmos) => TestTableClient_Cosmos}/TestServiceErrors.yaml (100%) rename sdk/tables/aztables/recordings/{tableClientLiveTests(storage) => TestTableClient_Storage}/TestAddEntity-variables.yaml (100%) rename sdk/tables/aztables/recordings/{tableClientLiveTests(storage) => TestTableClient_Storage}/TestAddEntity.yaml (100%) rename sdk/tables/aztables/recordings/{tableClientLiveTests(storage) => TestTableClient_Storage}/TestCreateTable-variables.yaml (100%) rename sdk/tables/aztables/recordings/{tableClientLiveTests(storage) => TestTableClient_Storage}/TestCreateTable.yaml (100%) rename sdk/tables/aztables/recordings/{tableClientLiveTests(storage) => TestTableClient_Storage}/TestQuerySimpleEntity-variables.yaml (100%) rename sdk/tables/aztables/recordings/{tableClientLiveTests(storage) => TestTableClient_Storage}/TestQuerySimpleEntity.yaml (100%) rename sdk/tables/aztables/recordings/{tableClientLiveTests(storage) => TestTableClient_Storage}/TestServiceErrors-variables.yaml (100%) rename sdk/tables/aztables/recordings/{tableClientLiveTests(storage) => TestTableClient_Storage}/TestServiceErrors.yaml (100%) diff --git a/sdk/internal/testframework/recording.go b/sdk/internal/testframework/recording.go index 8fc89dacc7fa..61738a1ea998 100644 --- a/sdk/internal/testframework/recording.go +++ b/sdk/internal/testframework/recording.go @@ -6,6 +6,7 @@ package testframework import ( + "errors" "fmt" "io/ioutil" "math/rand" @@ -27,8 +28,8 @@ type Recording struct { RecordingFile string VariablesFile string Mode RecordMode - variables map[string]string `yaml:"variables"` - previousSessionVariables map[string]string `yaml:"variables"` + variables map[string]*string `yaml:"variables"` + previousSessionVariables map[string]*string `yaml:"variables"` recorder *recorder.Recorder src rand.Source sanitizer *RecordingSanitizer @@ -65,9 +66,9 @@ const ( Secret_Base64String VariableType = "secret_base64String" ) -func NewRecording(c TestContext, mode RecordMode, testSuffixes ...string) (*Recording, error) { +func NewRecording(c TestContext, mode RecordMode) (*Recording, error) { // create recorder based on the test name, recordMode, variables, and sanitizers - recPath, varPath := getFilePaths(c.Name(), testSuffixes) + recPath, varPath := getFilePaths(c.Name()) rec, err := recorder.NewAsMode(recPath, modeMap[mode], nil) if err != nil { @@ -77,7 +78,7 @@ func NewRecording(c TestContext, mode RecordMode, testSuffixes ...string) (*Reco // If the mode is set in the environment, let that override the requested mode // This is to enable support for nightly live test pipelines envMode := GetOptionalEnv(ModeEnvironmentVariableName, string(mode)) - mode = RecordMode(envMode) + mode = RecordMode(*envMode) // initialize the Recording recording := &Recording{ @@ -85,8 +86,8 @@ func NewRecording(c TestContext, mode RecordMode, testSuffixes ...string) (*Reco RecordingFile: recPath + ".yaml", VariablesFile: varPath, Mode: mode, - variables: make(map[string]string), - previousSessionVariables: make(map[string]string), + variables: make(map[string]*string), + previousSessionVariables: make(map[string]*string), recorder: rec, c: c, } @@ -106,15 +107,22 @@ func NewRecording(c TestContext, mode RecordMode, testSuffixes ...string) (*Reco return recording, err } -// Gets a recorded variable. If the variable is not found we panic +// Gets a recorded variable. If the variable is not found we return an error // variableType is optional and defaults to Default -func (r *Recording) GetRecordedVariable(name string, variableType ...VariableType) string { +func (r *Recording) GetRecordedVariable(name string, variableType ...VariableType) (*string, error) { + var err error result, ok := r.previousSessionVariables[name] if !ok || r.Mode == Live { - result = GetRequiredEnv(name) - r.variables[name] = applyVariableOptions(&result, variableType...) + + result, err = GetRequiredEnv(name) + if err != nil { + r.c.Fail(err.Error()) + return nil, err + } else { + r.variables[name] = applyVariableOptions(result, variableType...) + } } - return result + return result, err } // Gets a recorded variable with a fallback default value @@ -123,9 +131,9 @@ func (r *Recording) GetOptionalRecordedVariable(name string, defaultValue string result, ok := r.previousSessionVariables[name] if !ok || r.Mode == Live { result = GetOptionalEnv(name, defaultValue) - r.variables[name] = applyVariableOptions(&result, variableType...) + r.variables[name] = applyVariableOptions(result, variableType...) } - return result + return *result } // To satisfy the azcore.Transport interface @@ -134,6 +142,7 @@ func (r *Recording) Do(req *http.Request) (*http.Response, error) { if err == cassette.ErrInteractionNotFound { error := missingRequestError(req) r.c.Fail(error) + return nil, errors.New(error) } return resp, err } @@ -178,32 +187,32 @@ func (r *Recording) Stop() error { return nil } -// Gets an environment variable by name and panics if it is not found -func GetRequiredEnv(name string) string { +// Gets an environment variable by name and returns an error if it is not found +func GetRequiredEnv(name string) (*string, error) { env, ok := os.LookupEnv(name) if ok { - return env + return &env, nil } else { - panic(envNotExistsError(name)) + return nil, errors.New(envNotExistsError(name)) } } // gets an environment variable by name and returns the defaultValue if not found -func GetOptionalEnv(name string, defaultValue string) string { +func GetOptionalEnv(name string, defaultValue string) *string { env, ok := os.LookupEnv(name) if ok { - return env + return &env } else { - return defaultValue + return &defaultValue } } // generate a recorded random alpha numeric id // if the recording has a randomSeed already set, the value will be generated from that seed, else a new random seed will be used -func (r *Recording) GenerateAlphaNumericId(prefix string, length int, lowercaseOnly bool) string { +func (r *Recording) GenerateAlphaNumericId(prefix string, length int, lowercaseOnly bool) (*string, error) { if length <= len(prefix) { - panic("length must be greater than prefix") + return nil, errors.New("length must be greater than prefix") } r.initRandomSource() @@ -231,8 +240,8 @@ func (r *Recording) GenerateAlphaNumericId(prefix string, length int, lowercaseO cache >>= letterIdxBits remain-- } - - return sb.String() + str := sb.String() + return &str, nil } func (r *Recording) matchRequest(req *http.Request, rec cassette.Request) bool { @@ -257,19 +266,21 @@ func envNotExistsError(varName string) string { // If variableType is not provided or Default, return result // If variableType is Secret_String, return SanitizedValue // If variableType isSecret_Base64String return SanitizedBase64Value -func applyVariableOptions(val *string, variableType ...VariableType) string { - +func applyVariableOptions(val *string, variableType ...VariableType) *string { + var ret string switch len(variableType) { case 0: - return *val + return val default: switch vt := variableType[0]; vt { case Secret_String: - return SanitizedValue + ret = SanitizedValue + return &ret case Secret_Base64String: - return SanitizedBase64Value + ret = SanitizedBase64Value + return &ret default: - return *val + return val } } } @@ -287,13 +298,14 @@ func (r *Recording) initRandomSource() { // check to see if we already have a random seed stored, use that if so seedString, ok := r.previousSessionVariables[randomSeedVariableName] if ok { - seed, err = strconv.ParseInt(seedString, 10, 64) + seed, err = strconv.ParseInt(*seedString, 10, 64) } // We did not have a random seed already stored; create a new one if !ok || err != nil || r.Mode == Live { seed = time.Now().Unix() - r.variables[randomSeedVariableName] = strconv.FormatInt(seed, 10) + val := strconv.FormatInt(seed, 10) + r.variables[randomSeedVariableName] = &val } // create a Source with the seed @@ -301,19 +313,8 @@ func (r *Recording) initRandomSource() { } // returns (recordingFilePath, variablesFilePath) -func getFilePaths(name string, suffixes []string) (string, string) { - testName := strings.SplitN(name, ".", 2) - var suffix string = "" - if len(suffixes) > 0 { - suffix = "(" + strings.Join(suffixes, ",") + ")" - } - var recPath string - if len(testName) == 2 { - - recPath = "recordings/" + testName[0] + suffix + "/" + testName[1] - } else { - recPath = "recordings/" + name - } +func getFilePaths(name string) (string, string) { + recPath := "recordings/" + name varPath := fmt.Sprintf("%s-variables.yaml", recPath) return recPath, varPath } @@ -345,6 +346,7 @@ func (r *Recording) unmarshalVariablesFile(out interface{}) error { if err != nil { // If the file or dir do not exist, this is not an error to report if os.IsNotExist(err) { + r.c.Log(fmt.Sprintf("Did not find recording for test '%s'", r.RecordingFile)) return nil } else { return err diff --git a/sdk/internal/testframework/recording_test.go b/sdk/internal/testframework/recording_test.go index 8f38b2d85fb6..ace6c8c7451f 100644 --- a/sdk/internal/testframework/recording_test.go +++ b/sdk/internal/testframework/recording_test.go @@ -62,13 +62,16 @@ func (r *recordingTests) Test_RecordedVariables(c *chk.C) { // optional variables always succeed. c.Assert(target.GetOptionalRecordedVariable(nonExistingEnvVar, expectedVariableValue), chk.Equals, expectedVariableValue) - // non existent variables panic - c.Assert(func() { target.GetRecordedVariable(nonExistingEnvVar) }, chk.Panics, envNotExistsError(nonExistingEnvVar)) + // non existent variables return an error + val, err := target.GetRecordedVariable(nonExistingEnvVar) + c.Succeed() + c.Assert(err.Error(), chk.Equals, envNotExistsError(nonExistingEnvVar)) // now create the env variable and check that it can be fetched os.Setenv(nonExistingEnvVar, expectedVariableValue) defer os.Unsetenv(nonExistingEnvVar) - c.Assert(target.GetRecordedVariable(nonExistingEnvVar), chk.Equals, expectedVariableValue) + val, err = target.GetRecordedVariable(nonExistingEnvVar) + c.Assert(*val, chk.Equals, expectedVariableValue) err = target.Stop() c.Assert(err, chk.IsNil) @@ -159,12 +162,12 @@ func (r *recordingTests) Test_GenerateAlphaNumericId(c *chk.C) { target, err := NewRecording(context, Playback) c.Assert(err, chk.IsNil) - generated1 := target.GenerateAlphaNumericId(prefix, 10, true) + generated1, err := target.GenerateAlphaNumericId(prefix, 10, true) - c.Assert(len(generated1), chk.Equals, 10) - c.Assert(strings.HasPrefix(generated1, prefix), chk.Equals, true) + c.Assert(len(*generated1), chk.Equals, 10) + c.Assert(strings.HasPrefix(*generated1, prefix), chk.Equals, true) - generated1a := target.GenerateAlphaNumericId(prefix, 10, true) + generated1a, err := target.GenerateAlphaNumericId(prefix, 10, true) c.Assert(generated1a, chk.Not(chk.Equals), generated1) err = target.Stop() @@ -173,10 +176,10 @@ func (r *recordingTests) Test_GenerateAlphaNumericId(c *chk.C) { target2, err := NewRecording(context, Playback) c.Assert(err, chk.IsNil) - generated2 := target2.GenerateAlphaNumericId(prefix, 10, true) + generated2, err := target2.GenerateAlphaNumericId(prefix, 10, true) // The two generated Ids should be the same since target2 loaded the saved random seed from target - c.Assert(generated1, chk.Equals, generated2) + c.Assert(*generated1, chk.Equals, *generated2) err = target.Stop() c.Assert(err, chk.IsNil) @@ -192,7 +195,8 @@ func (s *recordingTests) TestRecordRequestsAndDoMatching(c *chk.C) { target, err := NewRecording(context, Playback) target.recorder.SetTransport(rt) - reqUrl := server.URL() + "/" + target.GenerateAlphaNumericId("", 5, true) + path, err := target.GenerateAlphaNumericId("", 5, true) + reqUrl := server.URL() + "/" + *path req, _ := http.NewRequest(http.MethodPost, reqUrl, nil) @@ -213,7 +217,8 @@ func (s *recordingTests) TestRecordRequestsAndDoMatching(c *chk.C) { target.recorder.SetTransport(rt) // re-create the random url using the recorded variables - reqUrl = server.URL() + "/" + target.GenerateAlphaNumericId("", 5, true) + path, err = target.GenerateAlphaNumericId("", 5, true) + reqUrl = server.URL() + "/" + *path req, _ = http.NewRequest(http.MethodPost, reqUrl, nil) // playback the request @@ -232,7 +237,8 @@ func (s *recordingTests) TestRecordRequestsAndFailMatchingForMissingRecording(c target, err := NewRecording(context, Playback) target.recorder.SetTransport(rt) - reqUrl := server.URL() + "/" + target.GenerateAlphaNumericId("", 5, true) + path, err := target.GenerateAlphaNumericId("", 5, true) + reqUrl := server.URL() + "/" + *path req, _ := http.NewRequest(http.MethodPost, reqUrl, nil) @@ -257,7 +263,8 @@ func (s *recordingTests) TestRecordRequestsAndFailMatchingForMissingRecording(c req, _ = http.NewRequest(http.MethodPost, reqUrl, nil) // playback the request - c.Assert(func() { target.Do(req) }, chk.Panics, missingRequestError(req)) + _, err = target.Do(req) + c.Assert(err.Error(), chk.Equals, missingRequestError(req)) c.Succeed() err = target.Stop() c.Assert(err, chk.IsNil) diff --git a/sdk/internal/testframework/testcontext.go b/sdk/internal/testframework/testcontext.go index 028f53fd23c2..299ff494c477 100644 --- a/sdk/internal/testframework/testcontext.go +++ b/sdk/internal/testframework/testcontext.go @@ -21,13 +21,12 @@ type Failer func(string) type Logger func(string) type Name func() string -func NewTestContext(f Failer, l Logger, name Name) TestContext { - return &testContext{fail: f, log: l, name: name()} +func NewTestContext(failer Failer, logger Logger, name Name) TestContext { + return &testContext{fail: failer, log: logger, name: name()} } func (c *testContext) Fail(msg string) { c.fail(msg) - panic(msg) } func (c *testContext) Log(msg string) { c.log(msg) diff --git a/sdk/tables/aztables/go.mod b/sdk/tables/aztables/go.mod index 7c7e16da9401..24785c9a7ac4 100644 --- a/sdk/tables/aztables/go.mod +++ b/sdk/tables/aztables/go.mod @@ -7,5 +7,5 @@ replace github.com/Azure/azure-sdk-for-go/sdk/internal => ../../internal require ( github.com/Azure/azure-sdk-for-go/sdk/azcore v0.14.2 github.com/Azure/azure-sdk-for-go/sdk/internal v0.5.0 - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c + github.com/stretchr/testify v1.7.0 ) diff --git a/sdk/tables/aztables/go.sum b/sdk/tables/aztables/go.sum index bba755a4acb4..6ace2124b54d 100644 --- a/sdk/tables/aztables/go.sum +++ b/sdk/tables/aztables/go.sum @@ -1,5 +1,7 @@ github.com/Azure/azure-sdk-for-go/sdk/azcore v0.14.2 h1:jBp1eg+iY1S6SEjISakVfHmvDxfj8bg1Mw9JFwpCKag= github.com/Azure/azure-sdk-for-go/sdk/azcore v0.14.2/go.mod h1:pElNP+u99BvCZD+0jOlhI9OC/NB2IDTOTGZOZH0Qhq8= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dnaeon/go-vcr v1.1.0 h1:ReYa/UBrRyQdant9B4fNHGoCNKw6qh6P0fsdGmZpR7c= github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= @@ -8,6 +10,11 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -26,3 +33,5 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestCreateTable-variables.yaml b/sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestCreateTable-variables.yaml similarity index 100% rename from sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestCreateTable-variables.yaml rename to sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestCreateTable-variables.yaml diff --git a/sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestCreateTable.yaml b/sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestCreateTable.yaml similarity index 100% rename from sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestCreateTable.yaml rename to sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestCreateTable.yaml diff --git a/sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestQueryTable-variables.yaml b/sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestQueryTable-variables.yaml similarity index 100% rename from sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestQueryTable-variables.yaml rename to sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestQueryTable-variables.yaml diff --git a/sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestQueryTable.yaml b/sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestQueryTable.yaml similarity index 100% rename from sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestQueryTable.yaml rename to sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestQueryTable.yaml diff --git a/sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestServiceErrors-variables.yaml b/sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestServiceErrors-variables.yaml similarity index 100% rename from sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestServiceErrors-variables.yaml rename to sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestServiceErrors-variables.yaml diff --git a/sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestServiceErrors.yaml b/sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestServiceErrors.yaml similarity index 100% rename from sdk/tables/aztables/recordings/tableServiceClientLiveTests(cosmos)/TestServiceErrors.yaml rename to sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestServiceErrors.yaml diff --git a/sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestCreateTable-variables.yaml b/sdk/tables/aztables/recordings/TestServiceClient_Storage/TestCreateTable-variables.yaml similarity index 100% rename from sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestCreateTable-variables.yaml rename to sdk/tables/aztables/recordings/TestServiceClient_Storage/TestCreateTable-variables.yaml diff --git a/sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestCreateTable.yaml b/sdk/tables/aztables/recordings/TestServiceClient_Storage/TestCreateTable.yaml similarity index 100% rename from sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestCreateTable.yaml rename to sdk/tables/aztables/recordings/TestServiceClient_Storage/TestCreateTable.yaml diff --git a/sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestQueryTable-variables.yaml b/sdk/tables/aztables/recordings/TestServiceClient_Storage/TestQueryTable-variables.yaml similarity index 100% rename from sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestQueryTable-variables.yaml rename to sdk/tables/aztables/recordings/TestServiceClient_Storage/TestQueryTable-variables.yaml diff --git a/sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestQueryTable.yaml b/sdk/tables/aztables/recordings/TestServiceClient_Storage/TestQueryTable.yaml similarity index 100% rename from sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestQueryTable.yaml rename to sdk/tables/aztables/recordings/TestServiceClient_Storage/TestQueryTable.yaml diff --git a/sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestServiceErrors-variables.yaml b/sdk/tables/aztables/recordings/TestServiceClient_Storage/TestServiceErrors-variables.yaml similarity index 100% rename from sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestServiceErrors-variables.yaml rename to sdk/tables/aztables/recordings/TestServiceClient_Storage/TestServiceErrors-variables.yaml diff --git a/sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestServiceErrors.yaml b/sdk/tables/aztables/recordings/TestServiceClient_Storage/TestServiceErrors.yaml similarity index 100% rename from sdk/tables/aztables/recordings/tableServiceClientLiveTests(storage)/TestServiceErrors.yaml rename to sdk/tables/aztables/recordings/TestServiceClient_Storage/TestServiceErrors.yaml diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestAddEntity-variables.yaml b/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestAddEntity-variables.yaml similarity index 100% rename from sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestAddEntity-variables.yaml rename to sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestAddEntity-variables.yaml diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestAddEntity.yaml b/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestAddEntity.yaml similarity index 100% rename from sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestAddEntity.yaml rename to sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestAddEntity.yaml diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestCreateTable-variables.yaml b/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestCreateTable-variables.yaml similarity index 100% rename from sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestCreateTable-variables.yaml rename to sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestCreateTable-variables.yaml diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestCreateTable.yaml b/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestCreateTable.yaml similarity index 100% rename from sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestCreateTable.yaml rename to sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestCreateTable.yaml diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestQuerySimpleEntity-variables.yaml b/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestQuerySimpleEntity-variables.yaml similarity index 100% rename from sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestQuerySimpleEntity-variables.yaml rename to sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestQuerySimpleEntity-variables.yaml diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestQuerySimpleEntity.yaml b/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestQuerySimpleEntity.yaml similarity index 100% rename from sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestQuerySimpleEntity.yaml rename to sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestQuerySimpleEntity.yaml diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestServiceErrors-variables.yaml b/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestServiceErrors-variables.yaml similarity index 100% rename from sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestServiceErrors-variables.yaml rename to sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestServiceErrors-variables.yaml diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestServiceErrors.yaml b/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestServiceErrors.yaml similarity index 100% rename from sdk/tables/aztables/recordings/tableClientLiveTests(cosmos)/TestServiceErrors.yaml rename to sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestServiceErrors.yaml diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestAddEntity-variables.yaml b/sdk/tables/aztables/recordings/TestTableClient_Storage/TestAddEntity-variables.yaml similarity index 100% rename from sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestAddEntity-variables.yaml rename to sdk/tables/aztables/recordings/TestTableClient_Storage/TestAddEntity-variables.yaml diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestAddEntity.yaml b/sdk/tables/aztables/recordings/TestTableClient_Storage/TestAddEntity.yaml similarity index 100% rename from sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestAddEntity.yaml rename to sdk/tables/aztables/recordings/TestTableClient_Storage/TestAddEntity.yaml diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestCreateTable-variables.yaml b/sdk/tables/aztables/recordings/TestTableClient_Storage/TestCreateTable-variables.yaml similarity index 100% rename from sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestCreateTable-variables.yaml rename to sdk/tables/aztables/recordings/TestTableClient_Storage/TestCreateTable-variables.yaml diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestCreateTable.yaml b/sdk/tables/aztables/recordings/TestTableClient_Storage/TestCreateTable.yaml similarity index 100% rename from sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestCreateTable.yaml rename to sdk/tables/aztables/recordings/TestTableClient_Storage/TestCreateTable.yaml diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestQuerySimpleEntity-variables.yaml b/sdk/tables/aztables/recordings/TestTableClient_Storage/TestQuerySimpleEntity-variables.yaml similarity index 100% rename from sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestQuerySimpleEntity-variables.yaml rename to sdk/tables/aztables/recordings/TestTableClient_Storage/TestQuerySimpleEntity-variables.yaml diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestQuerySimpleEntity.yaml b/sdk/tables/aztables/recordings/TestTableClient_Storage/TestQuerySimpleEntity.yaml similarity index 100% rename from sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestQuerySimpleEntity.yaml rename to sdk/tables/aztables/recordings/TestTableClient_Storage/TestQuerySimpleEntity.yaml diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestServiceErrors-variables.yaml b/sdk/tables/aztables/recordings/TestTableClient_Storage/TestServiceErrors-variables.yaml similarity index 100% rename from sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestServiceErrors-variables.yaml rename to sdk/tables/aztables/recordings/TestTableClient_Storage/TestServiceErrors-variables.yaml diff --git a/sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestServiceErrors.yaml b/sdk/tables/aztables/recordings/TestTableClient_Storage/TestServiceErrors.yaml similarity index 100% rename from sdk/tables/aztables/recordings/tableClientLiveTests(storage)/TestServiceErrors.yaml rename to sdk/tables/aztables/recordings/TestTableClient_Storage/TestServiceErrors.yaml diff --git a/sdk/tables/aztables/tableClient_test.go b/sdk/tables/aztables/tableClient_test.go index 6e2376db00b6..77dc5e399514 100644 --- a/sdk/tables/aztables/tableClient_test.go +++ b/sdk/tables/aztables/tableClient_test.go @@ -8,61 +8,71 @@ import ( "testing" "github.com/Azure/azure-sdk-for-go/sdk/internal/testframework" - chk "gopkg.in/check.v1" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" ) type tableClientLiveTests struct { + suite.Suite endpointType EndpointType mode testframework.RecordMode } // Hookup to the testing framework -func Test(t *testing.T) { chk.TestingT(t) } +func TestTableClient_Storage(t *testing.T) { + storage := tableClientLiveTests{endpointType: StorageEndpoint, mode: testframework.Playback /* change to Record to re-record tests */} + suite.Run(t, &storage) +} -// wire up chk to testing -var _ = chk.Suite(&tableClientLiveTests{endpointType: StorageEndpoint, mode: testframework.Playback /* change to Record to re-record tests */}) -var _ = chk.Suite(&tableClientLiveTests{endpointType: CosmosEndpoint, mode: testframework.Playback /* change to Record to re-record tests */}) +// Hookup to the testing framework +func TestTableClient_Cosmos(t *testing.T) { + cosmos := tableClientLiveTests{endpointType: CosmosEndpoint, mode: testframework.Playback /* change to Record to re-record tests */} + suite.Run(t, &cosmos) +} -func (s *tableClientLiveTests) TestServiceErrors(c *chk.C) { - client, delete := s.init(c, true) +func (s *tableClientLiveTests) TestServiceErrors() { + client, delete := s.init(true) defer delete() // Create a duplicate table to produce an error _, err := client.Create(ctx) - c.Assert(err.RawResponse().StatusCode, chk.Equals, http.StatusConflict) + assert.Equal(s.T(), err.RawResponse().StatusCode, http.StatusConflict) } -func (s *tableClientLiveTests) TestCreateTable(c *chk.C) { - client, delete := s.init(c, false) +func (s *tableClientLiveTests) TestCreateTable() { + assert := assert.New(s.T()) + client, delete := s.init(false) defer delete() resp, err := client.Create(ctx) - c.Assert(err, chk.IsNil) - c.Assert(*resp.TableResponse.TableName, chk.Equals, client.Name()) + assert.Nil(err) + assert.Equal(*resp.TableResponse.TableName, client.Name()) } -func (s *tableClientLiveTests) TestAddEntity(c *chk.C) { - client, delete := s.init(c, true) +func (s *tableClientLiveTests) TestAddEntity() { + assert := assert.New(s.T()) + client, delete := s.init(true) defer delete() entitiesToCreate := createSimpleEntities(1, "partition") for _, e := range *entitiesToCreate { _, err := client.AddEntity(ctx, &e) - c.Assert(err, chk.IsNil) + assert.Nil(err) } } -func (s *tableClientLiveTests) TestQuerySimpleEntity(c *chk.C) { - client, delete := s.init(c, true) +func (s *tableClientLiveTests) TestQuerySimpleEntity() { + assert := assert.New(s.T()) + client, delete := s.init(true) defer delete() // Add 5 entities entitiesToCreate := createSimpleEntities(5, "partition") for _, e := range *entitiesToCreate { _, err := client.AddEntity(ctx, &e) - c.Assert(err, chk.IsNil) + assert.Nil(err) } filter := "RowKey lt '5'" @@ -71,46 +81,47 @@ func (s *tableClientLiveTests) TestQuerySimpleEntity(c *chk.C) { pager := client.Query(QueryOptions{Filter: &filter}) for pager.NextPage(ctx) { resp = pager.PageResponse() - c.Assert(len(*resp.TableEntityQueryResponse.Value), chk.Equals, expectedCount) + assert.Equal(len(*resp.TableEntityQueryResponse.Value), expectedCount) } resp = pager.PageResponse() - c.Assert(pager.Err(), chk.IsNil) + assert.Nil(pager.Err()) for _, e := range *resp.TableEntityQueryResponse.Value { _, ok := e[PartitionKey].(string) - c.Assert(ok, chk.Equals, true) + assert.True(ok) _, ok = e[RowKey].(string) - c.Assert(ok, chk.Equals, true) + assert.True(ok) _, ok = e[Timestamp].(string) - c.Assert(ok, chk.Equals, true) + assert.True(ok) _, ok = e[EtagOdata].(string) - c.Assert(ok, chk.Equals, true) + assert.True(ok) _, ok = e["StringProp"].(string) - c.Assert(ok, chk.Equals, true) + assert.True(ok) //TODO: fix when serialization is implemented _, ok = e["IntProp"].(float64) - c.Assert(ok, chk.Equals, true) + assert.True(ok) _, ok = e["BoolProp"].(bool) - c.Assert(ok, chk.Equals, true) + assert.True(ok) } } -func (s *tableClientLiveTests) SetUpTest(c *chk.C) { - // setup the test environment - recordedTestSetup(c, testKey(c, s.endpointType), s.endpointType, s.mode) +// setup the test environment +func (s *tableClientLiveTests) BeforeTest(suite string, test string) { + recordedTestSetup(s.T(), s.T().Name(), s.endpointType, s.mode) } -func (s *tableClientLiveTests) TearDownTest(c *chk.C) { - // teardown the test context - recordedTestTeardown(testKey(c, s.endpointType)) +// teardown the test context +func (s *tableClientLiveTests) AfterTest(suite string, test string) { + recordedTestTeardown(s.T().Name()) } -func (s *tableClientLiveTests) init(c *chk.C, doCreate bool) (*TableClient, func()) { - context := getTestContext(testKey(c, s.endpointType)) - tableName := getTableName(context) - client := context.client.GetTableClient(tableName) +func (s *tableClientLiveTests) init(doCreate bool) (*TableClient, func()) { + assert := assert.New(s.T()) + context := getTestContext(s.T().Name()) + tableName, _ := getTableName(context) + client := context.client.GetTableClient(*tableName) if doCreate { _, err := client.Create(ctx) - c.Assert(err, chk.IsNil) + assert.Nil(err) } return client, func() { client.Delete(ctx) diff --git a/sdk/tables/aztables/tableServiceClient_test.go b/sdk/tables/aztables/tableServiceClient_test.go index d0cbf39c070b..1e62c0ad6183 100644 --- a/sdk/tables/aztables/tableServiceClient_test.go +++ b/sdk/tables/aztables/tableServiceClient_test.go @@ -6,46 +6,60 @@ package aztables import ( "fmt" "net/http" + "testing" "github.com/Azure/azure-sdk-for-go/sdk/internal/testframework" - chk "gopkg.in/check.v1" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" ) type tableServiceClientLiveTests struct { + suite.Suite endpointType EndpointType mode testframework.RecordMode } // Hookup to the testing framework -var _ = chk.Suite(&tableServiceClientLiveTests{endpointType: StorageEndpoint, mode: testframework.Playback /* change to Record to re-record tests */}) -var _ = chk.Suite(&tableServiceClientLiveTests{endpointType: CosmosEndpoint, mode: testframework.Playback /* change to Record to re-record tests */}) +func TestServiceClient_Storage(t *testing.T) { + storage := tableServiceClientLiveTests{endpointType: StorageEndpoint, mode: testframework.Playback /* change to Record to re-record tests */} + suite.Run(t, &storage) +} + +// Hookup to the testing framework +func TestServiceClient_Cosmos(t *testing.T) { + cosmos := tableServiceClientLiveTests{endpointType: CosmosEndpoint, mode: testframework.Playback /* change to Record to re-record tests */} + suite.Run(t, &cosmos) +} -func (s *tableServiceClientLiveTests) TestServiceErrors(c *chk.C) { - context := getTestContext(testKey(c, s.endpointType)) - tableName := getTableName(context) +func (s *tableServiceClientLiveTests) TestServiceErrors() { + assert := assert.New(s.T()) + context := getTestContext(s.T().Name()) + tableName, err := getTableName(context) - _, err := context.client.Create(ctx, tableName) - defer context.client.Delete(ctx, tableName) - c.Assert(err, chk.IsNil) + _, err = context.client.Create(ctx, *tableName) + defer context.client.Delete(ctx, *tableName) + assert.Nil(err) // Create a duplicate table to produce an error - _, err = context.client.Create(ctx, tableName) - c.Assert(err.RawResponse().StatusCode, chk.Equals, http.StatusConflict) + _, svcErr := context.client.Create(ctx, *tableName) + assert.Equal(svcErr.RawResponse().StatusCode, http.StatusConflict) } -func (s *tableServiceClientLiveTests) TestCreateTable(c *chk.C) { - context := getTestContext(testKey(c, s.endpointType)) - tableName := getTableName(context) +func (s *tableServiceClientLiveTests) TestCreateTable() { + assert := assert.New(s.T()) + context := getTestContext(s.T().Name()) + tableName, err := getTableName(context) - resp, err := context.client.Create(ctx, tableName) - defer context.client.Delete(ctx, tableName) + resp, err := context.client.Create(ctx, *tableName) + defer context.client.Delete(ctx, *tableName) - c.Assert(err, chk.IsNil) - c.Assert(*resp.TableResponse.TableName, chk.Equals, tableName) + assert.Nil(err) + assert.Equal(*resp.TableResponse.TableName, *tableName) } -func (s *tableServiceClientLiveTests) TestQueryTable(c *chk.C) { - context := getTestContext(testKey(c, s.endpointType)) +func (s *tableServiceClientLiveTests) TestQueryTable() { + assert := assert.New(s.T()) + context := getTestContext(s.T().Name()) tableCount := 5 tableNames := make([]string, tableCount) prefix1 := "zzza" @@ -55,12 +69,14 @@ func (s *tableServiceClientLiveTests) TestQueryTable(c *chk.C) { //create 10 tables with our exected prefix and 1 with a different prefix for i := 0; i < tableCount; i++ { if i < (tableCount - 1) { - tableNames[i] = getTableName(context, prefix1) + name, _ := getTableName(context, prefix1) + tableNames[i] = *name } else { - tableNames[i] = getTableName(context, prefix2) + name, _ := getTableName(context, prefix2) + tableNames[i] = *name } _, err := context.client.Create(ctx, tableNames[i]) - c.Assert(err, chk.IsNil) + assert.Nil(err) } // Query for tables with no pagination. The filter should exclude one table from the results @@ -73,8 +89,8 @@ func (s *tableServiceClientLiveTests) TestQueryTable(c *chk.C) { resultCount += len(*resp.TableQueryResponse.Value) } - c.Assert(pager.Err(), chk.IsNil) - c.Assert(resultCount, chk.Equals, tableCount-1) + assert.Nil(pager.Err()) + assert.Equal(resultCount, tableCount-1) // Query for tables with pagination top := int32(2) @@ -88,17 +104,17 @@ func (s *tableServiceClientLiveTests) TestQueryTable(c *chk.C) { pageCount++ } - c.Assert(pager.Err(), chk.IsNil) - c.Assert(resultCount, chk.Equals, tableCount-1) - c.Assert(pageCount, chk.Equals, int(top)) + assert.Nil(pager.Err()) + assert.Equal(resultCount, tableCount-1) + assert.Equal(pageCount, int(top)) } -func (s *tableServiceClientLiveTests) SetUpTest(c *chk.C) { +func (s *tableServiceClientLiveTests) BeforeTest(suite string, test string) { // setup the test environment - recordedTestSetup(c, testKey(c, s.endpointType), s.endpointType, s.mode) + recordedTestSetup(s.T(), s.T().Name(), s.endpointType, s.mode) } -func (s *tableServiceClientLiveTests) TearDownTest(c *chk.C) { +func (s *tableServiceClientLiveTests) AfterTest(suite string, test string) { // teardown the test context - recordedTestTeardown(testKey(c, s.endpointType)) + recordedTestTeardown(s.T().Name()) } diff --git a/sdk/tables/aztables/zt_tableRecordedTests.go b/sdk/tables/aztables/zt_tableRecordedTests.go index 587e78cb38b5..5226744376f2 100644 --- a/sdk/tables/aztables/zt_tableRecordedTests.go +++ b/sdk/tables/aztables/zt_tableRecordedTests.go @@ -6,11 +6,11 @@ package aztables import ( "context" "fmt" + "testing" "github.com/Azure/azure-sdk-for-go/sdk/azcore" "github.com/Azure/azure-sdk-for-go/sdk/internal/testframework" - - chk "gopkg.in/check.v1" + "github.com/stretchr/testify/assert" ) type tablesRecordedTests struct{} @@ -51,36 +51,43 @@ func cosmosURI(accountName string, endpointSuffix string) string { } // create the test specific TableClient and wire it up to recordings -func recordedTestSetup(c *chk.C, testName string, endpointType EndpointType, mode testframework.RecordMode) { - var accountName string +func recordedTestSetup(t *testing.T, testName string, endpointType EndpointType, mode testframework.RecordMode) { + var accountName *string var suffix string var cred *SharedKeyCredential + var secret *string var uri string + assert := assert.New(t) // init the test framework - context := testframework.NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) - recording, err := testframework.NewRecording(context, mode, string(endpointType)) - c.Assert(err, chk.IsNil) + context := testframework.NewTestContext(func(msg string) { assert.FailNow(msg) }, func(msg string) { t.Log(msg) }, func() string { return testName }) + recording, err := testframework.NewRecording(context, mode) + assert.Nil(err) if endpointType == StorageEndpoint { - accountName = recording.GetRecordedVariable(storageAccountNameEnvVar) + accountName, err = recording.GetRecordedVariable(storageAccountNameEnvVar) suffix = recording.GetOptionalRecordedVariable(storageEndpointSuffixEnvVar, DefaultStorageSuffix) - cred, _ = NewSharedKeyCredential(accountName, recording.GetRecordedVariable(storageAccountKeyEnvVar, testframework.Secret_Base64String)) - uri = storageURI(accountName, suffix) + secret, err = recording.GetRecordedVariable(storageAccountKeyEnvVar, testframework.Secret_Base64String) + cred, _ = NewSharedKeyCredential(*accountName, *secret) + uri = storageURI(*accountName, suffix) } else { - accountName = recording.GetRecordedVariable(cosmosAccountNameEnnVar) + accountName, err = recording.GetRecordedVariable(cosmosAccountNameEnnVar) suffix = recording.GetOptionalRecordedVariable(cosmosEndpointSuffixEnvVar, DefaultCosmosSuffix) - cred, _ = NewSharedKeyCredential(accountName, recording.GetRecordedVariable(cosmosAccountKeyEnvVar, testframework.Secret_Base64String)) - uri = cosmosURI(accountName, suffix) + secret, err = recording.GetRecordedVariable(cosmosAccountKeyEnvVar, testframework.Secret_Base64String) + cred, _ = NewSharedKeyCredential(*accountName, *secret) + uri = cosmosURI(*accountName, suffix) } client, err := NewTableServiceClient(uri, cred, &TableClientOptions{HTTPClient: recording, Retry: azcore.RetryOptions{MaxRetries: -1}}) - c.Assert(err, chk.IsNil) + assert.Nil(err) clientsMap[testName] = &testContext{client: client, recording: recording} } func recordedTestTeardown(key string) { - clientsMap[key].recording.Stop() + context, ok := clientsMap[key] + if ok { + context.recording.Stop() + } } // cleans up the specified tables. If tables is nil, all tables will be deleted @@ -104,7 +111,7 @@ func getTestContext(key string) *testContext { return clientsMap[key] } -func getTableName(context *testContext, prefix ...string) string { +func getTableName(context *testContext, prefix ...string) (*string, error) { if len(prefix) == 0 { return context.recording.GenerateAlphaNumericId(tableNamePrefix, 20, true) } else { @@ -112,10 +119,6 @@ func getTableName(context *testContext, prefix ...string) string { } } -func testKey(c *chk.C, ep EndpointType) string { - return c.TestName() + string(ep) -} - func createSimpleEntities(count int, pk string) *[]map[string]interface{} { result := make([]map[string]interface{}, count) From c983287ea2ff8883025d4071fcd6d574c13eab55 Mon Sep 17 00:00:00 2001 From: Christopher Scott Date: Wed, 7 Apr 2021 21:37:02 -0500 Subject: [PATCH 06/18] refactor tests to testify --- sdk/internal/go.mod | 3 +- sdk/internal/go.sum | 31 ++-- .../testframework/recording_sanitizer_test.go | 72 ++++---- sdk/internal/testframework/recording_test.go | 157 ++++++++++-------- sdk/internal/testframework/request_matcher.go | 3 +- .../testframework/request_matcher_test.go | 114 +++++-------- 6 files changed, 182 insertions(+), 198 deletions(-) diff --git a/sdk/internal/go.mod b/sdk/internal/go.mod index 55f016992352..c23772f28d9d 100644 --- a/sdk/internal/go.mod +++ b/sdk/internal/go.mod @@ -3,9 +3,8 @@ module github.com/Azure/azure-sdk-for-go/sdk/internal go 1.14 require ( - github.com/Azure/azure-sdk-for-go/sdk/azcore v0.14.2 // indirect github.com/dnaeon/go-vcr v1.1.0 + github.com/stretchr/testify v1.7.0 golang.org/x/net v0.0.0-20201010224723-4f7140c49acb - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c gopkg.in/yaml.v2 v2.4.0 ) diff --git a/sdk/internal/go.sum b/sdk/internal/go.sum index cadb7b65ee19..7c8192467fcd 100644 --- a/sdk/internal/go.sum +++ b/sdk/internal/go.sum @@ -1,40 +1,29 @@ -github.com/Azure/azure-sdk-for-go/sdk/azcore v0.14.2 h1:jBp1eg+iY1S6SEjISakVfHmvDxfj8bg1Mw9JFwpCKag= -github.com/Azure/azure-sdk-for-go/sdk/azcore v0.14.2/go.mod h1:pElNP+u99BvCZD+0jOlhI9OC/NB2IDTOTGZOZH0Qhq8= -github.com/Azure/azure-sdk-for-go/sdk/internal v0.5.0/go.mod h1:k4KbFSunV/+0hOHL1vyFaPsiYQ1Vmvy1TBpmtvCDLZM= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dnaeon/go-vcr v1.1.0 h1:ReYa/UBrRyQdant9B4fNHGoCNKw6qh6P0fsdGmZpR7c= github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20201010224723-4f7140c49acb h1:mUVeFHoDKis5nxCAzoAi7E8Ghb86EXh/RK6wtvJIqRY= golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c h1:KHUzaHIpjWVlVVNh65G3hhuj3KB1HnjY6Cq5cTvRQT8= -golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/sdk/internal/testframework/recording_sanitizer_test.go b/sdk/internal/testframework/recording_sanitizer_test.go index 4fadba6c3bda..951897485073 100644 --- a/sdk/internal/testframework/recording_sanitizer_test.go +++ b/sdk/internal/testframework/recording_sanitizer_test.go @@ -14,27 +14,30 @@ import ( "github.com/Azure/azure-sdk-for-go/sdk/internal/mock" "github.com/dnaeon/go-vcr/cassette" "github.com/dnaeon/go-vcr/recorder" - chk "gopkg.in/check.v1" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" ) -type recordingSanitizerTests struct{} - -// Hookup to the testing framework -func Test(t *testing.T) { chk.TestingT(t) } - -var _ = chk.Suite(&recordingSanitizerTests{}) +type recordingSanitizerTests struct { + suite.Suite +} const authHeader string = "Authorization" const customHeader1 string = "Fooheader" const customHeader2 string = "Barheader" const nonSanitizedHeader string = "notsanitized" -func (s *recordingSanitizerTests) TestDefaultSanitizerSanitizesAuthHeader(c *chk.C) { +func TestRecordingSanitizer(t *testing.T) { + suite.Run(t, new(recordingSanitizerTests)) +} + +func (s *recordingSanitizerTests) TestDefaultSanitizerSanitizesAuthHeader() { + assert := assert.New(s.T()) server, cleanup := mock.NewServer() server.SetResponse() defer cleanup() rt := NewMockRoundTripper(server) - r, _ := recorder.NewAsMode(getTestFileName(c, false), recorder.ModeRecording, rt) + r, _ := recorder.NewAsMode(getTestFileName(s.T(), false), recorder.ModeRecording, rt) DefaultSanitizer(r) @@ -44,22 +47,23 @@ func (s *recordingSanitizerTests) TestDefaultSanitizerSanitizesAuthHeader(c *chk r.RoundTrip(req) r.Stop() - c.Assert(req.Header.Get(authHeader), chk.Equals, SanitizedValue) + assert.Equal(SanitizedValue, req.Header.Get(authHeader)) - rec, err := cassette.Load(getTestFileName(c, false)) - c.Assert(err, chk.IsNil) + rec, err := cassette.Load(getTestFileName(s.T(), false)) + assert.Nil(err) for _, i := range rec.Interactions { - c.Assert(i.Request.Headers.Get(authHeader), chk.Equals, SanitizedValue) + assert.Equal(SanitizedValue, i.Request.Headers.Get(authHeader)) } } -func (s *recordingSanitizerTests) TestAddSanitizedHeadersSanitizes(c *chk.C) { +func (s *recordingSanitizerTests) TestAddSanitizedHeadersSanitizes() { + assert := assert.New(s.T()) server, cleanup := mock.NewServer() server.SetResponse() defer cleanup() rt := NewMockRoundTripper(server) - r, _ := recorder.NewAsMode(getTestFileName(c, false), recorder.ModeRecording, rt) + r, _ := recorder.NewAsMode(getTestFileName(s.T(), false), recorder.ModeRecording, rt) target := DefaultSanitizer(r) target.AddSanitizedHeaders(customHeader1, customHeader2) @@ -73,26 +77,27 @@ func (s *recordingSanitizerTests) TestAddSanitizedHeadersSanitizes(c *chk.C) { r.RoundTrip(req) r.Stop() - c.Assert(req.Header.Get(customHeader1), chk.Equals, SanitizedValue) - c.Assert(req.Header.Get(customHeader2), chk.Equals, SanitizedValue) - c.Assert(req.Header.Get(nonSanitizedHeader), chk.Equals, safeValue) + assert.Equal(SanitizedValue, req.Header.Get(customHeader1)) + assert.Equal(SanitizedValue, req.Header.Get(customHeader2)) + assert.Equal(safeValue, req.Header.Get(nonSanitizedHeader)) - rec, err := cassette.Load(getTestFileName(c, false)) - c.Assert(err, chk.IsNil) + rec, err := cassette.Load(getTestFileName(s.T(), false)) + assert.Nil(err) for _, i := range rec.Interactions { - c.Assert(i.Request.Headers.Get(customHeader1), chk.Equals, SanitizedValue) - c.Assert(i.Request.Headers.Get(customHeader2), chk.Equals, SanitizedValue) - c.Assert(i.Request.Headers.Get(nonSanitizedHeader), chk.Equals, safeValue) + assert.Equal(SanitizedValue, i.Request.Headers.Get(customHeader1)) + assert.Equal(SanitizedValue, i.Request.Headers.Get(customHeader2)) + assert.Equal(safeValue, i.Request.Headers.Get(nonSanitizedHeader)) } } -func (s *recordingSanitizerTests) TestAddUrlSanitizerSanitizes(c *chk.C) { +func (s *recordingSanitizerTests) TestAddUrlSanitizerSanitizes() { + assert := assert.New(s.T()) server, cleanup := mock.NewServer() server.SetResponse(mock.WithStatusCode(http.StatusNoContent)) defer cleanup() rt := NewMockRoundTripper(server) - r, _ := recorder.NewAsMode(getTestFileName(c, false), recorder.ModeRecording, rt) + r, _ := recorder.NewAsMode(getTestFileName(s.T(), false), recorder.ModeRecording, rt) sanitizedUrl := server.URL() secret := "/secretvalue" @@ -108,23 +113,24 @@ func (s *recordingSanitizerTests) TestAddUrlSanitizerSanitizes(c *chk.C) { r.RoundTrip(req) r.Stop() - rec, err := cassette.Load(getTestFileName(c, false)) - c.Assert(err, chk.IsNil) + rec, err := cassette.Load(getTestFileName(s.T(), false)) + assert.Nil(err) for _, i := range rec.Interactions { - c.Assert(i.Request.URL, chk.Not(chk.Equals), sanitizedUrl+secret) - c.Assert(i.Request.URL, chk.Equals, sanitizedUrl) + assert.NotEqual(sanitizedUrl+secret, i.Request.URL) + assert.Equal(sanitizedUrl, i.Request.URL) } } -func (s *recordingSanitizerTests) TearDownSuite(c *chk.C) { +func (s *recordingSanitizerTests) TearDownSuite() { + assert := assert.New(s.T()) // cleanup test files err := os.RemoveAll("testfiles") - c.Log(err) + assert.Nil(err) } -func getTestFileName(c *chk.C, addSuffix bool) string { - name := "testfiles/" + c.TestName() +func getTestFileName(t *testing.T, addSuffix bool) string { + name := "testfiles/" + t.Name() if addSuffix { name = name + ".yaml" } diff --git a/sdk/internal/testframework/recording_test.go b/sdk/internal/testframework/recording_test.go index ace6c8c7451f..f2d4e10f2cca 100644 --- a/sdk/internal/testframework/recording_test.go +++ b/sdk/internal/testframework/recording_test.go @@ -10,81 +10,90 @@ import ( "net/http" "os" "strings" + "testing" "github.com/Azure/azure-sdk-for-go/sdk/internal/mock" "github.com/dnaeon/go-vcr/cassette" - - chk "gopkg.in/check.v1" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" ) -type recordingTests struct{} +type recordingTests struct { + suite.Suite +} -var _ = chk.Suite(&recordingTests{}) +func TestRecording(t *testing.T) { + suite.Run(t, new(recordingTests)) +} -func (r *recordingTests) Test_InitializeRecording(c *chk.C) { - context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) +func (s *recordingTests) Test_InitializeRecording() { + assert := assert.New(s.T()) + context := NewTestContext(func(msg string) { assert.FailNow(msg) }, func(msg string) { s.T().Log(msg) }, func() string { return s.T().Name() }) expectedMode := Playback target, err := NewRecording(context, expectedMode) - c.Assert(err, chk.IsNil) - c.Assert(target.RecordingFile, chk.NotNil) - c.Assert(target.VariablesFile, chk.NotNil) - c.Assert(target.Mode, chk.Equals, expectedMode) + assert.Nil(err) + assert.NotNil(target.RecordingFile) + assert.NotNil(target.VariablesFile) + assert.Equal(expectedMode, target.Mode) err = target.Stop() - c.Assert(err, chk.IsNil) + assert.Nil(err) } -func (r *recordingTests) Test_StopDoesNotSaveVariablesWhenNoVariablesExist(c *chk.C) { - context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) +func (s *recordingTests) Test_StopDoesNotSaveVariablesWhenNoVariablesExist() { + assert := assert.New(s.T()) + context := NewTestContext(func(msg string) { assert.FailNow(msg) }, func(msg string) { s.T().Log(msg) }, func() string { return s.T().Name() }) target, err := NewRecording(context, Playback) - c.Assert(err, chk.IsNil) + assert.Nil(err) err = target.Stop() - c.Assert(err, chk.IsNil) + assert.Nil(err) _, err = ioutil.ReadFile(target.VariablesFile) - c.Assert(os.IsNotExist(err), chk.Equals, true) + assert.Equal(true, os.IsNotExist(err)) } -func (r *recordingTests) Test_RecordedVariables(c *chk.C) { - context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) +func (s *recordingTests) Test_RecordedVariables() { + assert := assert.New(s.T()) + context := NewTestContext(func(msg string) { s.T().Log(msg) }, func(msg string) { s.T().Log(msg) }, func() string { return s.T().Name() }) nonExistingEnvVar := "nonExistingEnvVar" expectedVariableValue := "foobar" variablesMap := map[string]string{} target, err := NewRecording(context, Playback) - c.Assert(err, chk.IsNil) + assert.Nil(err) // optional variables always succeed. - c.Assert(target.GetOptionalRecordedVariable(nonExistingEnvVar, expectedVariableValue), chk.Equals, expectedVariableValue) + assert.Equal(expectedVariableValue, target.GetOptionalRecordedVariable(nonExistingEnvVar, expectedVariableValue)) // non existent variables return an error val, err := target.GetRecordedVariable(nonExistingEnvVar) - c.Succeed() - c.Assert(err.Error(), chk.Equals, envNotExistsError(nonExistingEnvVar)) + // mark test as succeeded + assert.Equal(envNotExistsError(nonExistingEnvVar), err.Error()) // now create the env variable and check that it can be fetched os.Setenv(nonExistingEnvVar, expectedVariableValue) defer os.Unsetenv(nonExistingEnvVar) val, err = target.GetRecordedVariable(nonExistingEnvVar) - c.Assert(*val, chk.Equals, expectedVariableValue) + assert.Equal(expectedVariableValue, *val) err = target.Stop() - c.Assert(err, chk.IsNil) + assert.Nil(err) // check that a variables file was created with the correct variable target.unmarshalVariablesFile(variablesMap) actualValue, ok := variablesMap[nonExistingEnvVar] - c.Assert(ok, chk.Equals, true) - c.Assert(actualValue, chk.Equals, expectedVariableValue) + assert.Equal(true, ok) + assert.Equal(expectedVariableValue, actualValue) } -func (r *recordingTests) Test_RecordedVariablesSanitized(c *chk.C) { - context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) +func (s *recordingTests) Test_RecordedVariablesSanitized() { + assert := assert.New(s.T()) + context := NewTestContext(func(msg string) { assert.FailNow(msg) }, func(msg string) { s.T().Log(msg) }, func() string { return s.T().Name() }) SanitizedStringVar := "sanitizedvar" SanitizedBase64StrigVar := "sanitizedbase64var" @@ -93,100 +102,103 @@ func (r *recordingTests) Test_RecordedVariablesSanitized(c *chk.C) { variablesMap := map[string]string{} target, err := NewRecording(context, Playback) - c.Assert(err, chk.IsNil) + assert.Nil(err) // call GetOptionalRecordedVariable with the Secret_String VariableType arg - c.Assert(target.GetOptionalRecordedVariable(SanitizedStringVar, secret, Secret_String), chk.Equals, secret) + assert.Equal(secret, target.GetOptionalRecordedVariable(SanitizedStringVar, secret, Secret_String)) // call GetOptionalRecordedVariable with the Secret_Base64String VariableType arg - c.Assert(target.GetOptionalRecordedVariable(SanitizedBase64StrigVar, secretBase64, Secret_Base64String), chk.Equals, secretBase64) + assert.Equal(secretBase64, target.GetOptionalRecordedVariable(SanitizedBase64StrigVar, secretBase64, Secret_Base64String)) // Calling Stop will save the variables and apply the sanitization options err = target.Stop() - c.Assert(err, chk.IsNil) + assert.Nil(err) // check that a variables file was created with the correct variables target.unmarshalVariablesFile(variablesMap) actualValue, ok := variablesMap[SanitizedStringVar] - c.Assert(ok, chk.Equals, true) + assert.Equal(true, ok) // the saved value is sanitized - c.Assert(actualValue, chk.Equals, SanitizedValue) + assert.Equal(SanitizedValue, actualValue) target.unmarshalVariablesFile(variablesMap) actualValue, ok = variablesMap[SanitizedBase64StrigVar] - c.Assert(ok, chk.Equals, true) + assert.Equal(true, ok) // the saved value is sanitized - c.Assert(actualValue, chk.Equals, SanitizedBase64Value) + assert.Equal(SanitizedBase64Value, actualValue) } -func (r *recordingTests) Test_StopSavesVariablesIfExistAndReadsPreviousVariables(c *chk.C) { - context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) +func (s *recordingTests) Test_StopSavesVariablesIfExistAndReadsPreviousVariables() { + assert := assert.New(s.T()) + context := NewTestContext(func(msg string) { assert.FailNow(msg) }, func(msg string) { s.T().Log(msg) }, func() string { return s.T().Name() }) expectedVariableName := "someVariable" expectedVariableValue := "foobar" variablesMap := map[string]string{} target, err := NewRecording(context, Playback) - c.Assert(err, chk.IsNil) + assert.Nil(err) target.GetOptionalRecordedVariable(expectedVariableName, expectedVariableValue) err = target.Stop() - c.Assert(err, chk.IsNil) + assert.Nil(err) // check that a variables file was created with the correct variable target.unmarshalVariablesFile(variablesMap) actualValue, ok := variablesMap[expectedVariableName] - c.Assert(ok, chk.Equals, true) - c.Assert(actualValue, chk.Equals, expectedVariableValue) + assert.Equal(true, ok) + assert.Equal(expectedVariableValue, actualValue) variablesMap = map[string]string{} target2, err := NewRecording(context, Playback) - c.Assert(err, chk.IsNil) + assert.Nil(err) err = target.Stop() - c.Assert(err, chk.IsNil) + assert.Nil(err) // check that a variables file was created with the variables loaded from the previous recording target2.unmarshalVariablesFile(variablesMap) actualValue, ok = variablesMap[expectedVariableName] - c.Assert(ok, chk.Equals, true) - c.Assert(actualValue, chk.Equals, expectedVariableValue) + assert.Equal(true, ok) + assert.Equal(expectedVariableValue, actualValue) } -func (r *recordingTests) Test_GenerateAlphaNumericId(c *chk.C) { - context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) +func (s *recordingTests) Test_GenerateAlphaNumericId() { + assert := assert.New(s.T()) + context := NewTestContext(func(msg string) { assert.FailNow(msg) }, func(msg string) { s.T().Log(msg) }, func() string { return s.T().Name() }) prefix := "myprefix" target, err := NewRecording(context, Playback) - c.Assert(err, chk.IsNil) + assert.Nil(err) generated1, err := target.GenerateAlphaNumericId(prefix, 10, true) - c.Assert(len(*generated1), chk.Equals, 10) - c.Assert(strings.HasPrefix(*generated1, prefix), chk.Equals, true) + assert.Equal(10, len(*generated1)) + assert.Equal(true, strings.HasPrefix(*generated1, prefix)) generated1a, err := target.GenerateAlphaNumericId(prefix, 10, true) - c.Assert(generated1a, chk.Not(chk.Equals), generated1) + assert.NotEqual(generated1, generated1a) err = target.Stop() - c.Assert(err, chk.IsNil) + assert.Nil(err) target2, err := NewRecording(context, Playback) - c.Assert(err, chk.IsNil) + assert.Nil(err) generated2, err := target2.GenerateAlphaNumericId(prefix, 10, true) // The two generated Ids should be the same since target2 loaded the saved random seed from target - c.Assert(*generated1, chk.Equals, *generated2) + assert.Equal(*generated2, *generated1) err = target.Stop() - c.Assert(err, chk.IsNil) + assert.Nil(err) } -func (s *recordingTests) TestRecordRequestsAndDoMatching(c *chk.C) { - context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) +func (s *recordingTests) TestRecordRequestsAndDoMatching() { + assert := assert.New(s.T()) + context := NewTestContext(func(msg string) { assert.FailNow(msg) }, func(msg string) { s.T().Log(msg) }, func() string { return s.T().Name() }) server, cleanup := mock.NewServer() server.SetResponse() defer cleanup() @@ -203,13 +215,13 @@ func (s *recordingTests) TestRecordRequestsAndDoMatching(c *chk.C) { // record the request target.Do(req) err = target.Stop() - c.Assert(err, chk.IsNil) + assert.Nil(err) rec, err := cassette.Load(target.SessionName) - c.Assert(err, chk.IsNil) + assert.Nil(err) for _, i := range rec.Interactions { - c.Assert(i.Request.URL, chk.Equals, reqUrl) + assert.Equal(reqUrl, i.Request.URL) } // re-initialize the recording @@ -224,11 +236,12 @@ func (s *recordingTests) TestRecordRequestsAndDoMatching(c *chk.C) { // playback the request target.Do(req) err = target.Stop() - c.Assert(err, chk.IsNil) + assert.Nil(err) } -func (s *recordingTests) TestRecordRequestsAndFailMatchingForMissingRecording(c *chk.C) { - context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) +func (s *recordingTests) TestRecordRequestsAndFailMatchingForMissingRecording() { + assert := assert.New(s.T()) + context := NewTestContext(func(msg string) { s.T().Log(msg) }, func(msg string) { s.T().Log(msg) }, func() string { return s.T().Name() }) server, cleanup := mock.NewServer() server.SetResponse() defer cleanup() @@ -245,13 +258,13 @@ func (s *recordingTests) TestRecordRequestsAndFailMatchingForMissingRecording(c // record the request target.Do(req) err = target.Stop() - c.Assert(err, chk.IsNil) + assert.Nil(err) rec, err := cassette.Load(target.SessionName) - c.Assert(err, chk.IsNil) + assert.Nil(err) for _, i := range rec.Interactions { - c.Assert(i.Request.URL, chk.Equals, reqUrl) + assert.Equal(reqUrl, i.Request.URL) } // re-initialize the recording @@ -264,15 +277,15 @@ func (s *recordingTests) TestRecordRequestsAndFailMatchingForMissingRecording(c // playback the request _, err = target.Do(req) - c.Assert(err.Error(), chk.Equals, missingRequestError(req)) - c.Succeed() + assert.Equal(missingRequestError(req), err.Error()) + // mark succeeded err = target.Stop() - c.Assert(err, chk.IsNil) + assert.Nil(err) } -func (r *recordingTests) TearDownSuite(c *chk.C) { +func (s *recordingTests) TearDownSuite() { // cleanup test files err := os.RemoveAll("recordings") - c.Log(err) + assert.Nil(s.T(), err) } diff --git a/sdk/internal/testframework/request_matcher.go b/sdk/internal/testframework/request_matcher.go index c0c633597a5a..38997a5ffa50 100644 --- a/sdk/internal/testframework/request_matcher.go +++ b/sdk/internal/testframework/request_matcher.go @@ -35,6 +35,7 @@ var requestHeaderMissing = "Test recording headers do not match. Header '%s' is var headerValuesMismatch = "Test recording header '%s' does not match. request: %s, recording: %s" var methodMismatch = "Test recording methods do not match. request: %s, recording: %s" var urlMismatch = "Test recording URLs do not match. request: %s, recording: %s" +var bodiesMismatch = "Test recording bodies do not match.\nrequest: %s\nrecording: %s" func compareBodies(r *http.Request, i cassette.Request, c TestContext) bool { body := bytes.Buffer{} @@ -47,7 +48,7 @@ func compareBodies(r *http.Request, i cassette.Request, c TestContext) bool { } bodiesMatch := body.String() == i.Body if !bodiesMatch { - c.Log(fmt.Sprintf("Test recording bodies do not match.\nrequest: %s\nrecording: %s", body.String(), i.Body)) + c.Log(fmt.Sprintf(bodiesMismatch, body.String(), i.Body)) } return bodiesMatch } diff --git a/sdk/internal/testframework/request_matcher_test.go b/sdk/internal/testframework/request_matcher_test.go index da9fa41e8f0f..90c945458917 100644 --- a/sdk/internal/testframework/request_matcher_test.go +++ b/sdk/internal/testframework/request_matcher_test.go @@ -6,49 +6,52 @@ package testframework import ( - "fmt" "io" "io/ioutil" "net/http" "net/url" "strings" + "testing" "github.com/Azure/azure-sdk-for-go/sdk/internal/uuid" "github.com/dnaeon/go-vcr/cassette" - - chk "gopkg.in/check.v1" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" ) -type requestMatcherTests struct{} +type requestMatcherTests struct { + suite.Suite +} + +func TestRequestMatcher(t *testing.T) { + suite.Run(t, new(requestMatcherTests)) +} const matchedBody string = "Matching body." const unMatchedBody string = "This body does not match." -// Hookup to the testing framework -var _ = chk.Suite(&requestMatcherTests{}) - -func (s *requestMatcherTests) TestCompareBodies(c *chk.C) { - context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) +func (s *requestMatcherTests) TestCompareBodies() { + assert := assert.New(s.T()) + context := NewTestContext(func(msg string) { assert.FailNow(msg) }, func(msg string) { s.T().Log(msg) }, func() string { return s.T().Name() }) req := http.Request{Body: closerFromString(matchedBody)} recReq := cassette.Request{Body: matchedBody} isMatch := compareBodies(&req, recReq, context) - c.Assert(isMatch, chk.Equals, true) + assert.Equal(true, isMatch) // make the requests mis-match req.Body = closerFromString((unMatchedBody)) isMatch = compareBodies(&req, recReq, context) - c.Assert(isMatch, chk.Equals, false) - log := c.GetTestLog() - c.Assert(strings.HasPrefix(log, "Test recording bodies do not match"), chk.Equals, true) + assert.False(isMatch) } -func (s *requestMatcherTests) TestCompareHeadersIgnoresIgnoredHeaders(c *chk.C) { - context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) +func (s *requestMatcherTests) TestCompareHeadersIgnoresIgnoredHeaders() { + assert := assert.New(s.T()) + context := NewTestContext(func(msg string) { assert.FailNow(msg) }, func(msg string) { s.T().Log(msg) }, func() string { return s.T().Name() }) // populate only ignored headers that do not match reqHeaders := make(http.Header) @@ -61,14 +64,13 @@ func (s *requestMatcherTests) TestCompareHeadersIgnoresIgnoredHeaders(c *chk.C) req := http.Request{Header: reqHeaders} recReq := cassette.Request{Headers: recordedHeaders} - isMatch := compareHeaders(&req, recReq, context) - // All headers match - c.Assert(isMatch, chk.Equals, true) + assert.True(compareHeaders(&req, recReq, context)) } -func (s *requestMatcherTests) TestCompareHeadersMatchesHeaders(c *chk.C) { - context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) +func (s *requestMatcherTests) TestCompareHeadersMatchesHeaders() { + assert := assert.New(s.T()) + context := NewTestContext(func(msg string) { assert.FailNow(msg) }, func(msg string) { s.T().Log(msg) }, func() string { return s.T().Name() }) // populate only ignored headers that do not match reqHeaders := make(http.Header) @@ -82,14 +84,12 @@ func (s *requestMatcherTests) TestCompareHeadersMatchesHeaders(c *chk.C) { req := http.Request{Header: reqHeaders} recReq := cassette.Request{Headers: recordedHeaders} - c.Assert( - compareHeaders(&req, recReq, context), - chk.Equals, - true) + assert.True(compareHeaders(&req, recReq, context)) } -func (s *requestMatcherTests) TestCompareHeadersFailsMissingRecHeader(c *chk.C) { - context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) +func (s *requestMatcherTests) TestCompareHeadersFailsMissingRecHeader() { + assert := assert.New(s.T()) + context := NewTestContext(func(msg string) { assert.FailNow(msg) }, func(msg string) { s.T().Log(msg) }, func() string { return s.T().Name() }) // populate only ignored headers that do not match reqHeaders := make(http.Header) @@ -107,15 +107,12 @@ func (s *requestMatcherTests) TestCompareHeadersFailsMissingRecHeader(c *chk.C) // add a new header to the just req reqHeaders[header2] = headerValue - c.Assert( - compareHeaders(&req, recReq, context), - chk.Equals, - false) - c.Assert(c.GetTestLog(), chk.Equals, fmt.Sprintf(recordingHeaderMissing+"\n", header2)) + assert.False(compareHeaders(&req, recReq, context)) } -func (s *requestMatcherTests) TestCompareHeadersFailsMissingReqHeader(c *chk.C) { - context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) +func (s *requestMatcherTests) TestCompareHeadersFailsMissingReqHeader() { + assert := assert.New(s.T()) + context := NewTestContext(func(msg string) { assert.FailNow(msg) }, func(msg string) { s.T().Log(msg) }, func() string { return s.T().Name() }) // populate only ignored headers that do not match reqHeaders := make(http.Header) @@ -133,15 +130,12 @@ func (s *requestMatcherTests) TestCompareHeadersFailsMissingReqHeader(c *chk.C) // add a new header to just the recording recordedHeaders[header2] = headerValue - c.Assert( - compareHeaders(&req, recReq, context), - chk.Equals, - false) - c.Assert(c.GetTestLog(), chk.Equals, fmt.Sprintf(requestHeaderMissing+"\n", header2)) + assert.False(compareHeaders(&req, recReq, context)) } -func (s *requestMatcherTests) TestCompareHeadersFailsMismatchedValues(c *chk.C) { - context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) +func (s *requestMatcherTests) TestCompareHeadersFailsMismatchedValues() { + assert := assert.New(s.T()) + context := NewTestContext(func(msg string) { assert.FailNow(msg) }, func(msg string) { s.T().Log(msg) }, func() string { return s.T().Name() }) // populate only ignored headers that do not match reqHeaders := make(http.Header) @@ -161,55 +155,37 @@ func (s *requestMatcherTests) TestCompareHeadersFailsMismatchedValues(c *chk.C) recordedHeaders[header2] = headerValue reqHeaders[header2] = mismatch - c.Assert( - compareHeaders(&req, recReq, context), - chk.Equals, - false) - c.Assert(c.GetTestLog(), chk.Equals, fmt.Sprintf(headerValuesMismatch+"\n", header2, mismatch, headerValue)) + assert.False(compareHeaders(&req, recReq, context)) } -func (s *requestMatcherTests) TestCompareURLs(c *chk.C) { - context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) +func (s *requestMatcherTests) TestCompareURLs() { + assert := assert.New(s.T()) + context := NewTestContext(func(msg string) { assert.FailNow(msg) }, func(msg string) { s.T().Log(msg) }, func() string { return s.T().Name() }) scheme := "https" host := "foo.bar" req := http.Request{URL: &url.URL{Scheme: scheme, Host: host}} recReq := cassette.Request{URL: scheme + "://" + host} - c.Assert( - compareURLs(&req, recReq, context), - chk.Equals, - true) + assert.True(compareURLs(&req, recReq, context)) req.URL.Path = "noMatch" - c.Assert( - compareURLs(&req, recReq, context), - chk.Equals, - false) - - c.Assert(c.GetTestLog(), chk.Equals, fmt.Sprintf(urlMismatch+"\n", req.URL.String(), recReq.URL)) + assert.False(compareURLs(&req, recReq, context)) } -func (s *requestMatcherTests) TestCompareMethods(c *chk.C) { - context := NewTestContext(func(msg string) { c.Log(msg); c.Fail() }, func(msg string) { c.Log(msg) }, func() string { return c.TestName() }) +func (s *requestMatcherTests) TestCompareMethods() { + assert := assert.New(s.T()) + context := NewTestContext(func(msg string) { assert.FailNow(msg) }, func(msg string) { s.T().Log(msg) }, func() string { return s.T().Name() }) methodPost := "POST" methodPatch := "PATCH" req := http.Request{Method: methodPost} recReq := cassette.Request{Method: methodPost} - c.Assert( - compareMethods(&req, recReq, context), - chk.Equals, - true) + assert.True(compareMethods(&req, recReq, context)) req.Method = methodPatch - c.Assert( - compareMethods(&req, recReq, context), - chk.Equals, - false) - - c.Assert(c.GetTestLog(), chk.Equals, fmt.Sprintf(methodMismatch+"\n", req.Method, recReq.Method)) + assert.False(compareMethods(&req, recReq, context)) } func closerFromString(content string) io.ReadCloser { From 3d1ebab6357373a6dfc7e5a58fd02986d45030e3 Mon Sep 17 00:00:00 2001 From: Christopher Scott Date: Thu, 8 Apr 2021 00:02:24 -0500 Subject: [PATCH 07/18] entity parsing --- sdk/tables/aztables/go.mod | 1 + sdk/tables/aztables/go.sum | 2 + sdk/tables/aztables/zc_table_pagers.go | 75 ++++++++++++--------- sdk/tables/aztables/zc_table_pagers_test.go | 60 +++++++++++++++++ 4 files changed, 106 insertions(+), 32 deletions(-) create mode 100644 sdk/tables/aztables/zc_table_pagers_test.go diff --git a/sdk/tables/aztables/go.mod b/sdk/tables/aztables/go.mod index 24785c9a7ac4..d19e9f2dac53 100644 --- a/sdk/tables/aztables/go.mod +++ b/sdk/tables/aztables/go.mod @@ -7,5 +7,6 @@ replace github.com/Azure/azure-sdk-for-go/sdk/internal => ../../internal require ( github.com/Azure/azure-sdk-for-go/sdk/azcore v0.14.2 github.com/Azure/azure-sdk-for-go/sdk/internal v0.5.0 + github.com/google/uuid v1.2.0 // indirect github.com/stretchr/testify v1.7.0 ) diff --git a/sdk/tables/aztables/go.sum b/sdk/tables/aztables/go.sum index 6ace2124b54d..d5cfe51f882e 100644 --- a/sdk/tables/aztables/go.sum +++ b/sdk/tables/aztables/go.sum @@ -4,6 +4,8 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dnaeon/go-vcr v1.1.0 h1:ReYa/UBrRyQdant9B4fNHGoCNKw6qh6P0fsdGmZpR7c= github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= +github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= diff --git a/sdk/tables/aztables/zc_table_pagers.go b/sdk/tables/aztables/zc_table_pagers.go index 73c5bbbd5bfb..85d4e8b4c314 100644 --- a/sdk/tables/aztables/zc_table_pagers.go +++ b/sdk/tables/aztables/zc_table_pagers.go @@ -5,6 +5,13 @@ package aztables import ( "context" + "errors" + "fmt" + "strconv" + "strings" + "time" + + "github.com/Azure/azure-sdk-for-go/sdk/internal/uuid" ) // Pager for Table entity queries @@ -92,36 +99,40 @@ func castAndRemoveAnnotationsSlice(entities *[]map[string]interface{}) { } -func castAndRemoveAnnotations(entity *map[string]interface{}) { - /* - foreach (var propertyName in entity.Keys) - { - var spanPropertyName = propertyName.AsSpan(); - var iSuffix = spanPropertyName.IndexOf(spanOdataSuffix); - if (iSuffix > 0) - { - // This property is an Odata annotation. Save it in the typeAnnoations dictionary. - typeAnnotationsWithKeys[spanPropertyName.Slice(0, iSuffix).ToString()] = ((entity[propertyName] as string)!, propertyName); - } - } - - // Iterate through the types that are serialized as string by default and Parse them as the correct type, as indicated by the type annotations. - foreach (var annotation in typeAnnotationsWithKeys.Keys) - { - entity[annotation] = typeAnnotationsWithKeys[annotation].TypeAnnotation switch - { - TableConstants.Odata.EdmBinary => Convert.FromBase64String(entity[annotation] as string), - TableConstants.Odata.EdmDateTime => DateTimeOffset.Parse(entity[annotation] as string, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind), - TableConstants.Odata.EdmGuid => Guid.Parse(entity[annotation] as string), - TableConstants.Odata.EdmInt64 => long.Parse(entity[annotation] as string, CultureInfo.InvariantCulture), - _ => throw new NotSupportedException("Not supported type " + typeAnnotationsWithKeys[annotation]) - }; - - // Remove the type annotation property from the dictionary. - entity.Remove(typeAnnotationsWithKeys[annotation].AnnotationKey); - } - */ - // for name, val := range *entity { - - // } +func castAndRemoveAnnotations(entity *map[string]interface{}) (*map[string]interface{}, error) { + value := (*entity)["value"].([]interface{})[0].(map[string]interface{}) + for k, v := range value { + + iSuffix := strings.Index(k, OdataType) + if iSuffix > 0 { + // Get the name of the property that this odataType key describes. + valueKey := k[0:iSuffix] + // get the string value of the value at the valueKey + valAsString := value[valueKey].(string) + + switch v { + case EdmBinary: + value[valueKey] = []byte(valAsString) + case EdmDateTime: + t, err := time.Parse(time.RFC3339Nano, valAsString) + if err != nil { + return nil, err + } + value[valueKey] = t + case EdmGuid: + value[valueKey] = uuid.Parse(valAsString) + case EdmInt64: + i, err := strconv.ParseInt(valAsString, 10, 64) + if err != nil { + return nil, err + } + value[valueKey] = i + default: + return nil, errors.New(fmt.Sprintf("unsupported annotation found: %s", k)) + } + // remove the annotation key + delete(value, k) + } + } + return &value, nil } diff --git a/sdk/tables/aztables/zc_table_pagers_test.go b/sdk/tables/aztables/zc_table_pagers_test.go new file mode 100644 index 000000000000..11dff822d4b2 --- /dev/null +++ b/sdk/tables/aztables/zc_table_pagers_test.go @@ -0,0 +1,60 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package aztables + +import ( + "io" + "io/ioutil" + "net/http" + "strings" + "testing" + "time" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/stretchr/testify/assert" +) + +type pagerTests struct{} + +func TestCastAndRemoveAnnotations(t *testing.T) { + assert := assert.New(t) + + r := &http.Response{Body: closerFromString(complexPayload)} + resp := azcore.Response{Response: r} + + var val map[string]interface{} + err := resp.UnmarshalAsJSON(&val) + assert.Nil(err) + entity, err := castAndRemoveAnnotations(&val) + assert.Nil(err) + // assert all odata annotations are removed. + for k, _ := range *entity { + assert.NotContains(k, OdataType) + } + + assert.IsType((*entity)["SomeDateProperty"], time.Now()) +} + +func closerFromString(content string) io.ReadCloser { + return ioutil.NopCloser(strings.NewReader(content)) +} + +const complexPayload = "{\"odata.metadata\": \"https://jverazsdkprim.table.core.windows.net/$metadata#testtableifprd13i\"," + + "\"value\": [" + + "{\"odata.etag\": \"W/\\u0022datetime\\u00272021-03-23T18%3A29%3A15.9686039Z\\u0027\\u0022\"," + + "\"PartitionKey\": \"somPartition\"," + + "\"RowKey\": \"01\"," + + "\"Timestamp\": \"2021-03-23T18:29:15.9686039Z\"," + + "\"SomeBinaryProperty@odata.type\": \"Edm.Binary\"," + + "\"SomeBinaryProperty\": \"AQIDBAU=\"," + + "\"SomeDateProperty@odata.type\": \"Edm.DateTime\"," + + "\"SomeDateProperty\": \"2020-01-01T01:02:00Z\"," + + "\"SomeDoubleProperty0\": 1.0," + + "\"SomeDoubleProperty1\": 1.5," + + "\"SomeGuidProperty@odata.type\": \"Edm.Guid\"," + + "\"SomeGuidProperty\": \"0d391d16-97f1-4b9a-be68-4cc871f90001\"," + + "\"SomeInt64Property@odata.type\": \"Edm.Int64\"," + + "\"SomeInt64Property\": \"1\"," + + "\"SomeIntProperty\": 1," + + "\"SomeStringProperty\": \"This is table entity number 01\" }] }" From f5fd86f59b56829a4480d0aac00d6921afde8057 Mon Sep 17 00:00:00 2001 From: Christopher Scott Date: Sat, 10 Apr 2021 18:44:13 -0500 Subject: [PATCH 08/18] wip --- sdk/internal/testframework/recording.go | 66 ++++++++++++--- sdk/internal/testframework/recording_test.go | 83 ++++++++++++++++--- sdk/internal/testframework/testcontext.go | 12 ++- sdk/internal/uuid/uuid.go | 13 +++ sdk/tables/aztables/tableClient.go | 17 +++- sdk/tables/aztables/tableClient_test.go | 37 ++++++++- sdk/tables/aztables/tableUUID.go | 34 ++++++++ sdk/tables/aztables/zc_tableConstants.go | 1 + sdk/tables/aztables/zc_table_pagers.go | 81 ++++++++++++++++++- sdk/tables/aztables/zc_table_pagers_test.go | 85 +++++++++++++++++++- sdk/tables/aztables/zt_tableRecordedTests.go | 47 ++++++++++- 11 files changed, 448 insertions(+), 28 deletions(-) create mode 100644 sdk/tables/aztables/tableUUID.go diff --git a/sdk/internal/testframework/recording.go b/sdk/internal/testframework/recording.go index 61738a1ea998..516579baadf3 100644 --- a/sdk/internal/testframework/recording.go +++ b/sdk/internal/testframework/recording.go @@ -17,9 +17,9 @@ import ( "strings" "time" + "github.com/Azure/azure-sdk-for-go/sdk/internal/uuid" "github.com/dnaeon/go-vcr/cassette" "github.com/dnaeon/go-vcr/recorder" - "gopkg.in/yaml.v2" ) @@ -32,6 +32,7 @@ type Recording struct { previousSessionVariables map[string]*string `yaml:"variables"` recorder *recorder.Recorder src rand.Source + now *time.Time sanitizer *RecordingSanitizer c TestContext } @@ -40,6 +41,7 @@ const ( alphanumericBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" alphanumericLowercaseBytes = "abcdefghijklmnopqrstuvwxyz1234567890" randomSeedVariableName = "randomSeed" + nowVariableName = "now" ModeEnvironmentVariableName = "AZURE_TEST_MODE" ) @@ -77,7 +79,7 @@ func NewRecording(c TestContext, mode RecordMode) (*Recording, error) { // If the mode is set in the environment, let that override the requested mode // This is to enable support for nightly live test pipelines - envMode := GetOptionalEnv(ModeEnvironmentVariableName, string(mode)) + envMode := getOptionalEnv(ModeEnvironmentVariableName, string(mode)) mode = RecordMode(*envMode) // initialize the Recording @@ -114,7 +116,7 @@ func (r *Recording) GetRecordedVariable(name string, variableType ...VariableTyp result, ok := r.previousSessionVariables[name] if !ok || r.Mode == Live { - result, err = GetRequiredEnv(name) + result, err = getRequiredEnv(name) if err != nil { r.c.Fail(err.Error()) return nil, err @@ -130,7 +132,7 @@ func (r *Recording) GetRecordedVariable(name string, variableType ...VariableTyp func (r *Recording) GetOptionalRecordedVariable(name string, defaultValue string, variableType ...VariableType) string { result, ok := r.previousSessionVariables[name] if !ok || r.Mode == Live { - result = GetOptionalEnv(name, defaultValue) + result = getOptionalEnv(name, defaultValue) r.variables[name] = applyVariableOptions(result, variableType...) } return *result @@ -156,9 +158,14 @@ func (r *Recording) Stop() error { } if len(r.variables) > 0 { - // Save the variables after merging them - - //TODO: Merge values from previousVariables that are not in variables to variables + // Merge values from previousVariables that are not in variables to variables + for k, v := range r.previousSessionVariables { + if _, ok := r.variables[k]; ok { + // skip variables that were new in the current session + continue + } + r.variables[k] = v + } // Marshal to YAML and save variables data, err := yaml.Marshal(r.variables) @@ -188,7 +195,7 @@ func (r *Recording) Stop() error { } // Gets an environment variable by name and returns an error if it is not found -func GetRequiredEnv(name string) (*string, error) { +func getRequiredEnv(name string) (*string, error) { env, ok := os.LookupEnv(name) if ok { return &env, nil @@ -198,7 +205,7 @@ func GetRequiredEnv(name string) (*string, error) { } // gets an environment variable by name and returns the defaultValue if not found -func GetOptionalEnv(name string, defaultValue string) *string { +func getOptionalEnv(name string, defaultValue string) *string { env, ok := os.LookupEnv(name) if ok { return &env @@ -207,6 +214,18 @@ func GetOptionalEnv(name string, defaultValue string) *string { } } +func (r *Recording) Now() time.Time { + r.initNow() + + return *r.now +} + +func (r *Recording) UUID() uuid.UUID { + r.initRandomSource() + + return uuid.FromSource(r.src) +} + // generate a recorded random alpha numeric id // if the recording has a randomSeed already set, the value will be generated from that seed, else a new random seed will be used func (r *Recording) GenerateAlphaNumericId(prefix string, length int, lowercaseOnly bool) (*string, error) { @@ -312,6 +331,35 @@ func (r *Recording) initRandomSource() { r.src = rand.NewSource(seed) } +// Initializes the Source to be used for random value creation in this Recording +func (r *Recording) initNow() { + // if we already have a now generated, return immediately + if r.now != nil { + return + } + + var err error + var nowStr *string + var newNow time.Time + + // check to see if we already have a random seed stored, use that if so + nowStr, ok := r.previousSessionVariables[nowVariableName] + if ok { + newNow, err = time.Parse(time.RFC3339Nano, *nowStr) + } + + // We did not have a random seed already stored; create a new one + if !ok || err != nil || r.Mode == Live { + newNow = time.Now() + nowStr = new(string) + *nowStr = newNow.Format(time.RFC3339Nano) + r.variables[nowVariableName] = nowStr + } + + // save the now value. + r.now = &newNow +} + // returns (recordingFilePath, variablesFilePath) func getFilePaths(name string) (string, string) { recPath := "recordings/" + name diff --git a/sdk/internal/testframework/recording_test.go b/sdk/internal/testframework/recording_test.go index f2d4e10f2cca..a008793cd304 100644 --- a/sdk/internal/testframework/recording_test.go +++ b/sdk/internal/testframework/recording_test.go @@ -6,11 +6,13 @@ package testframework import ( + "fmt" "io/ioutil" "net/http" "os" "strings" "testing" + "time" "github.com/Azure/azure-sdk-for-go/sdk/internal/mock" "github.com/dnaeon/go-vcr/cassette" @@ -26,7 +28,7 @@ func TestRecording(t *testing.T) { suite.Run(t, new(recordingTests)) } -func (s *recordingTests) Test_InitializeRecording() { +func (s *recordingTests) TestInitializeRecording() { assert := assert.New(s.T()) context := NewTestContext(func(msg string) { assert.FailNow(msg) }, func(msg string) { s.T().Log(msg) }, func() string { return s.T().Name() }) @@ -42,7 +44,7 @@ func (s *recordingTests) Test_InitializeRecording() { assert.Nil(err) } -func (s *recordingTests) Test_StopDoesNotSaveVariablesWhenNoVariablesExist() { +func (s *recordingTests) TestStopDoesNotSaveVariablesWhenNoVariablesExist() { assert := assert.New(s.T()) context := NewTestContext(func(msg string) { assert.FailNow(msg) }, func(msg string) { s.T().Log(msg) }, func() string { return s.T().Name() }) @@ -56,7 +58,7 @@ func (s *recordingTests) Test_StopDoesNotSaveVariablesWhenNoVariablesExist() { assert.Equal(true, os.IsNotExist(err)) } -func (s *recordingTests) Test_RecordedVariables() { +func (s *recordingTests) TestRecordedVariables() { assert := assert.New(s.T()) context := NewTestContext(func(msg string) { s.T().Log(msg) }, func(msg string) { s.T().Log(msg) }, func() string { return s.T().Name() }) @@ -91,7 +93,7 @@ func (s *recordingTests) Test_RecordedVariables() { assert.Equal(expectedVariableValue, actualValue) } -func (s *recordingTests) Test_RecordedVariablesSanitized() { +func (s *recordingTests) TestRecordedVariablesSanitized() { assert := assert.New(s.T()) context := NewTestContext(func(msg string) { assert.FailNow(msg) }, func(msg string) { s.T().Log(msg) }, func() string { return s.T().Name() }) @@ -128,12 +130,14 @@ func (s *recordingTests) Test_RecordedVariablesSanitized() { assert.Equal(SanitizedBase64Value, actualValue) } -func (s *recordingTests) Test_StopSavesVariablesIfExistAndReadsPreviousVariables() { +func (s *recordingTests) TestStopSavesVariablesIfExistAndReadsPreviousVariables() { assert := assert.New(s.T()) context := NewTestContext(func(msg string) { assert.FailNow(msg) }, func(msg string) { s.T().Log(msg) }, func() string { return s.T().Name() }) expectedVariableName := "someVariable" expectedVariableValue := "foobar" + addedVariableName := "addedVariable" + addedVariableValue := "fizzbuzz" variablesMap := map[string]string{} target, err := NewRecording(context, Playback) @@ -147,24 +151,85 @@ func (s *recordingTests) Test_StopSavesVariablesIfExistAndReadsPreviousVariables // check that a variables file was created with the correct variable target.unmarshalVariablesFile(variablesMap) actualValue, ok := variablesMap[expectedVariableName] - assert.Equal(true, ok) + assert.True(ok) assert.Equal(expectedVariableValue, actualValue) variablesMap = map[string]string{} target2, err := NewRecording(context, Playback) assert.Nil(err) - err = target.Stop() + // add a new variable to the existing batch + target2.GetOptionalRecordedVariable(addedVariableName, addedVariableValue) + + err = target2.Stop() assert.Nil(err) // check that a variables file was created with the variables loaded from the previous recording target2.unmarshalVariablesFile(variablesMap) + actualValue, ok = variablesMap[addedVariableName] + assert.Truef(ok, fmt.Sprintf("Should have found %s", addedVariableName)) + assert.Equal(addedVariableValue, actualValue) actualValue, ok = variablesMap[expectedVariableName] - assert.Equal(true, ok) + assert.Truef(ok, fmt.Sprintf("Should have found %s", expectedVariableName)) assert.Equal(expectedVariableValue, actualValue) } -func (s *recordingTests) Test_GenerateAlphaNumericId() { +func (s *recordingTests) TestUUID() { + assert := assert.New(s.T()) + context := NewTestContext(func(msg string) { assert.FailNow(msg) }, func(msg string) { s.T().Log(msg) }, func() string { return s.T().Name() }) + + target, err := NewRecording(context, Playback) + assert.Nil(err) + + recordedUUID1 := target.UUID() + recordedUUID1a := target.UUID() + assert.NotEqual(recordedUUID1.String(), recordedUUID1a.String()) + + err = target.Stop() + assert.Nil(err) + + target2, err := NewRecording(context, Playback) + assert.Nil(err) + + recordedUUID2 := target2.UUID() + + // The two generated UUIDs should be the same since target2 loaded the saved random seed from target + assert.Equal(recordedUUID1.String(), recordedUUID2.String()) + + err = target.Stop() + assert.Nil(err) +} + +func (s *recordingTests) TestNow() { + assert := assert.New(s.T()) + context := NewTestContext(func(msg string) { assert.FailNow(msg) }, func(msg string) { s.T().Log(msg) }, func() string { return s.T().Name() }) + + target, err := NewRecording(context, Playback) + assert.Nil(err) + + recordedNow1 := target.Now() + + time.Sleep(time.Millisecond * 100) + + recordedNow1a := target.Now() + assert.Equal(recordedNow1.UnixNano(), recordedNow1a.UnixNano()) + + err = target.Stop() + assert.Nil(err) + + target2, err := NewRecording(context, Playback) + assert.Nil(err) + + recordedNow2 := target2.Now() + + // The two generated nows should be the same since target2 loaded the saved random seed from target + assert.Equal(recordedNow1.UnixNano(), recordedNow2.UnixNano()) + + err = target.Stop() + assert.Nil(err) +} + +func (s *recordingTests) TestGenerateAlphaNumericId() { assert := assert.New(s.T()) context := NewTestContext(func(msg string) { assert.FailNow(msg) }, func(msg string) { s.T().Log(msg) }, func() string { return s.T().Name() }) diff --git a/sdk/internal/testframework/testcontext.go b/sdk/internal/testframework/testcontext.go index 299ff494c477..84579d5ccf62 100644 --- a/sdk/internal/testframework/testcontext.go +++ b/sdk/internal/testframework/testcontext.go @@ -9,12 +9,14 @@ type TestContext interface { Fail(string) Log(string) Name() string + IsFailed() bool } type testContext struct { - fail Failer - log Logger - name string + failed bool + fail Failer + log Logger + name string } type Failer func(string) @@ -26,6 +28,7 @@ func NewTestContext(failer Failer, logger Logger, name Name) TestContext { } func (c *testContext) Fail(msg string) { + c.failed = true c.fail(msg) } func (c *testContext) Log(msg string) { @@ -34,3 +37,6 @@ func (c *testContext) Log(msg string) { func (c *testContext) Name() string { return c.name } +func (c *testContext) IsFailed() bool { + return c.failed +} diff --git a/sdk/internal/uuid/uuid.go b/sdk/internal/uuid/uuid.go index 4b288d81fecd..2ed1dd7477eb 100644 --- a/sdk/internal/uuid/uuid.go +++ b/sdk/internal/uuid/uuid.go @@ -41,6 +41,19 @@ func New() UUID { return u } +func FromSource(src rand.Source) UUID { + u := UUID{} + // Set all bits to randomly (or pseudo-randomly) chosen values. + // math/rand.Read() is no-fail so we omit any error checking. + rnd := rand.New(src) + rnd.Read(u[:]) + u[8] = (u[8] | reservedRFC4122) & 0x7F // u.setVariant(ReservedRFC4122) + + var version byte = 4 + u[6] = (u[6] & 0xF) | (version << 4) // u.setVersion(4) + return u +} + // String returns an unparsed version of the generated UUID sequence. func (u UUID) String() string { return fmt.Sprintf("%x-%x-%x-%x-%x", u[0:4], u[4:6], u[6:8], u[8:10], u[10:]) diff --git a/sdk/tables/aztables/tableClient.go b/sdk/tables/aztables/tableClient.go index e72aebab42ef..e20db2738a89 100644 --- a/sdk/tables/aztables/tableClient.go +++ b/sdk/tables/aztables/tableClient.go @@ -44,7 +44,7 @@ func (t *TableClient) Query(queryOptions QueryOptions) TableEntityQueryResponseP } // Creates an entity -func (t *TableClient) AddEntity(ctx context.Context, entity *map[string]interface{}) (*TableInsertEntityResponse, *runtime.ResponseError) { +func (t *TableClient) AddMapEntity(ctx context.Context, entity *map[string]interface{}) (*TableInsertEntityResponse, *runtime.ResponseError) { resp, err := t.client.InsertEntity(ctx, t.name, &TableInsertEntityOptions{TableEntityProperties: entity, ResponsePreference: ResponseFormatReturnNoContent.ToPtr()}, &QueryOptions{}) if err == nil { insertResp := resp.(TableInsertEntityResponse) @@ -53,3 +53,18 @@ func (t *TableClient) AddEntity(ctx context.Context, entity *map[string]interfac return nil, convertErr(err) } } + +// Creates an entity +func (t *TableClient) AddEntity(ctx context.Context, entity interface{}) (*TableInsertEntityResponse, *runtime.ResponseError) { + entmap, err := toMap(entity) + if err != nil { + return nil, azcore.NewResponseError(err, nil).(*runtime.ResponseError) + } + resp, err := t.client.InsertEntity(ctx, t.name, &TableInsertEntityOptions{TableEntityProperties: entmap, ResponsePreference: ResponseFormatReturnNoContent.ToPtr()}, &QueryOptions{}) + if err == nil { + insertResp := resp.(TableInsertEntityResponse) + return &insertResp, nil + } else { + return nil, convertErr(err) + } +} diff --git a/sdk/tables/aztables/tableClient_test.go b/sdk/tables/aztables/tableClient_test.go index 77dc5e399514..01d18b9e0afb 100644 --- a/sdk/tables/aztables/tableClient_test.go +++ b/sdk/tables/aztables/tableClient_test.go @@ -4,6 +4,9 @@ package aztables import ( + "bytes" + "io" + "io/ioutil" "net/http" "testing" @@ -57,6 +60,20 @@ func (s *tableClientLiveTests) TestAddEntity() { entitiesToCreate := createSimpleEntities(1, "partition") + for _, e := range *entitiesToCreate { + _, err := client.AddMapEntity(ctx, &e) + assert.Nil(err) + } +} + +func (s *tableClientLiveTests) aTestAddComplexEntity() { + assert := assert.New(s.T()) + context := getTestContext(s.T().Name()) + client, delete := s.init(true) + defer delete() + + entitiesToCreate := createComplexEntities(context, 1, "partition") + for _, e := range *entitiesToCreate { _, err := client.AddEntity(ctx, &e) assert.Nil(err) @@ -71,7 +88,7 @@ func (s *tableClientLiveTests) TestQuerySimpleEntity() { // Add 5 entities entitiesToCreate := createSimpleEntities(5, "partition") for _, e := range *entitiesToCreate { - _, err := client.AddEntity(ctx, &e) + _, err := client.AddMapEntity(ctx, &e) assert.Nil(err) } @@ -121,9 +138,25 @@ func (s *tableClientLiveTests) init(doCreate bool) (*TableClient, func()) { client := context.client.GetTableClient(*tableName) if doCreate { _, err := client.Create(ctx) - assert.Nil(err) + if err != nil { + r := err.RawResponse() + assert.FailNow(r.Status) + } } return client, func() { client.Delete(ctx) } } + +func getStringFromBody(b io.ReadCloser) string { + body := bytes.Buffer{} + b.Close() + if b != nil { + _, err := body.ReadFrom(b) + if err != nil { + return "" + } + b = ioutil.NopCloser(&body) + } + return body.String() +} diff --git a/sdk/tables/aztables/tableUUID.go b/sdk/tables/aztables/tableUUID.go new file mode 100644 index 000000000000..bc1fc0e83cf0 --- /dev/null +++ b/sdk/tables/aztables/tableUUID.go @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package aztables + +import ( + "github.com/Azure/azure-sdk-for-go/sdk/internal/uuid" +) + +// UUID is a struct wrapper around the github.com/Azure/azure-sdk-for-go/sdk/internal/uuid type. +// This wrapper type assists in the proper serialization of uuid types to the Table service. +type UUID struct { + u uuid.UUID +} + +// New returns a new uuid using RFC 4122 algorithm. +func NewTableUUID() UUID { + return UUID{u: uuid.New()} +} + +// String returns an unparsed version of the generated UUID sequence. +func (u UUID) String() string { + return u.String() +} + +// Parse parses a string formatted as "003020100-0504-0706-0809-0a0b0c0d0e0f" +// or "{03020100-0504-0706-0809-0a0b0c0d0e0f}" into a UUID. +func Parse(uuidStr string) UUID { + return UUID{uuid.Parse(uuidStr)} +} + +func (u UUID) bytes() []byte { + return u.u[:] +} diff --git a/sdk/tables/aztables/zc_tableConstants.go b/sdk/tables/aztables/zc_tableConstants.go index 00e6885a30cb..e48f9e2b60b9 100644 --- a/sdk/tables/aztables/zc_tableConstants.go +++ b/sdk/tables/aztables/zc_tableConstants.go @@ -19,4 +19,5 @@ const ( EdmInt32 = "Edm.Int32" EdmInt64 = "Edm.Int64" Edm = "Edm.String" + ISO8601 = "2006-01-02T15:04:05.9999999Z" ) diff --git a/sdk/tables/aztables/zc_table_pagers.go b/sdk/tables/aztables/zc_table_pagers.go index 85d4e8b4c314..d63afc82c782 100644 --- a/sdk/tables/aztables/zc_table_pagers.go +++ b/sdk/tables/aztables/zc_table_pagers.go @@ -5,8 +5,10 @@ package aztables import ( "context" + "encoding/base64" "errors" "fmt" + "reflect" "strconv" "strings" "time" @@ -99,6 +101,8 @@ func castAndRemoveAnnotationsSlice(entities *[]map[string]interface{}) { } +// TODO: The default behavior of json.Unmarshal is to deserialize all json numbers as Float64. +// This can be a problem for table entities which store float and int differently func castAndRemoveAnnotations(entity *map[string]interface{}) (*map[string]interface{}, error) { value := (*entity)["value"].([]interface{})[0].(map[string]interface{}) for k, v := range value { @@ -114,7 +118,7 @@ func castAndRemoveAnnotations(entity *map[string]interface{}) (*map[string]inter case EdmBinary: value[valueKey] = []byte(valAsString) case EdmDateTime: - t, err := time.Parse(time.RFC3339Nano, valAsString) + t, err := time.Parse(ISO8601, valAsString) if err != nil { return nil, err } @@ -136,3 +140,78 @@ func castAndRemoveAnnotations(entity *map[string]interface{}) (*map[string]inter } return &value, nil } + +func toMap(ent interface{}) (*map[string]interface{}, error) { + entMap := make(map[string]interface{}) + var s reflect.Value + if reflect.ValueOf(ent).Kind() == reflect.Ptr { + s = reflect.ValueOf(ent).Elem() + } else { + s = reflect.ValueOf(&ent).Elem().Elem() + } + typeOfT := s.Type() + + for i := 0; i < s.NumField(); i++ { + v := s.Field(i) + Switch: + f := typeOfT.Field(i) + name := f.Name + // add odata annotations for the types that require it. + switch k := v.Type().Kind(); k { + case reflect.Array, reflect.Map, reflect.Slice: + if GetTypeArray(v.Interface()) != reflect.TypeOf(byte(0)) { + return nil, errors.New("arrays and slices must be of type byte") + } + // check if this is a uuid field as decorated by a tag + if _, ok := f.Tag.Lookup("uuid"); ok { + entMap[odataType(name)] = EdmGuid + u := v.Interface().([16]byte) + var uu uuid.UUID = u + entMap[name] = uu.String() + continue + } else { + entMap[odataType(name)] = EdmBinary + b := v.Interface().([]byte) + entMap[name] = base64.StdEncoding.EncodeToString(b) + continue + } + case reflect.Struct: + switch tn := v.Type().String(); tn { + case "time.Time": + entMap[odataType(name)] = EdmDateTime + time := v.Interface().(time.Time) + entMap[name] = time.UTC().Format(ISO8601) + continue + default: + return nil, errors.New(fmt.Sprintf("Invalid struct for entity field '%s' of type '%s'", typeOfT.Field(i).Name, tn)) + } + case reflect.Float32, reflect.Float64: + entMap[odataType(name)] = EdmDouble + case reflect.Int64: + entMap[odataType(name)] = EdmInt64 + i64 := v.Interface().(int64) + entMap[name] = strconv.FormatInt(i64, 10) + continue + case reflect.Ptr: + if v.IsNil() { + // if the pointer is nil, ignore it. + continue + } + // follow the pointer to the type and re-run the switch + v = v.Elem() + goto Switch + + // typeOfT.Field(i).Name, f.Type(), f.Interface()) + } + entMap[name] = v.Interface() + } + return &entMap, nil +} + +func odataType(n string) string { + return fmt.Sprintf("%s%s", n, OdataType) +} + +func GetTypeArray(arr interface{}) reflect.Type { + return reflect.TypeOf(arr).Elem() +} diff --git a/sdk/tables/aztables/zc_table_pagers_test.go b/sdk/tables/aztables/zc_table_pagers_test.go index 11dff822d4b2..6d44603b2918 100644 --- a/sdk/tables/aztables/zc_table_pagers_test.go +++ b/sdk/tables/aztables/zc_table_pagers_test.go @@ -4,14 +4,19 @@ package aztables import ( + "encoding/base64" + "encoding/json" "io" "io/ioutil" + "math" "net/http" + "strconv" "strings" "testing" "time" "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/internal/uuid" "github.com/stretchr/testify/assert" ) @@ -33,13 +38,91 @@ func TestCastAndRemoveAnnotations(t *testing.T) { assert.NotContains(k, OdataType) } - assert.IsType((*entity)["SomeDateProperty"], time.Now()) + assert.IsType(time.Now(), (*entity)["SomeDateProperty"]) + assert.IsType([]byte{}, (*entity)["SomeBinaryProperty"]) + assert.IsType(float64(0), (*entity)["SomeDoubleProperty0"]) + // TODO: fix this + // assert.IsType(int(0), (*entity)["SomeIntProperty"]) +} + +func TestToMap(t *testing.T) { + assert := assert.New(t) + + ent := createComplexEntity() + + entMap, err := toMap(ent) + assert.Nil(err) + + // Validate that we have all the @odata.type properties for types []byte, int64, float64, time.Time, and uuid + for k, v := range odataHintProps { + vv, ok := (*entMap)[odataType(k)] + assert.Truef(ok, "Should have found map key of name '%s'", odataType(k)) + assert.Equal(v, vv) + } + + // validate all the types were properly casted / converted + assert.Equal(ent.PartitionKey, (*entMap)["PartitionKey"]) + assert.Equal(ent.RowKey, (*entMap)["RowKey"]) + ts, _ := time.Parse(ISO8601, (*entMap)["Timestamp"].(string)) + assert.Equal(ent.Timestamp.UTC().String(), ts.String()) + assert.Equal(base64.StdEncoding.EncodeToString(ent.SomeBinaryProperty), string((*entMap)["SomeBinaryProperty"].(string))) + ts, _ = time.Parse(ISO8601, (*entMap)["SomeDateProperty"].(string)) + assert.Equal(ent.SomeDateProperty.UTC().String(), ts.String()) + assert.Equal(ent.SomeDoubleProperty0, (*entMap)["SomeDoubleProperty0"]) + assert.Equal(ent.SomeDoubleProperty1, (*entMap)["SomeDoubleProperty1"]) + var u uuid.UUID = ent.SomeGuidProperty + assert.Equal(u.String(), (*entMap)["SomeGuidProperty"].(string)) + assert.Equal(strconv.FormatInt(ent.SomeInt64Property, 10), (*entMap)["SomeInt64Property"].(string)) + assert.Equal(ent.SomeIntProperty, (*entMap)["SomeIntProperty"]) + assert.Equal(ent.SomeStringProperty, (*entMap)["SomeStringProperty"]) + assert.Equal(*ent.SomePtrStringProperty, (*entMap)["SomePtrStringProperty"]) +} + +func TestEntitySerialization(t *testing.T) { + assert := assert.New(t) + + ent := createComplexEntity() + + b, err := json.Marshal(ent) + assert.Nil(err) + assert.NotEmpty(b) + s := string(b) + //assert.FailNow(s) + assert.NotEmpty(s) +} + +func createComplexEntity() complexEntity { + sp := "some pointer to string" + var e = complexEntity{ + PartitionKey: "partition", + ETag: "*", + RowKey: "row", + Timestamp: time.Now(), + SomeBinaryProperty: []byte("some bytes"), + SomeDateProperty: time.Now(), + SomeDoubleProperty0: float64(1), + SomeDoubleProperty1: float64(1.2345), + SomeGuidProperty: uuid.New(), + SomeInt64Property: math.MaxInt64, + SomeIntProperty: 42, + SomeStringProperty: "some string", + SomePtrStringProperty: &sp} + return e } func closerFromString(content string) io.ReadCloser { return ioutil.NopCloser(strings.NewReader(content)) } +var odataHintProps = map[string]string{ + "Timestamp": EdmDateTime, + "SomeBinaryProperty": EdmBinary, + "SomeDateProperty": EdmDateTime, + "SomeDoubleProperty0": EdmDouble, + "SomeDoubleProperty1": EdmDouble, + "SomeGuidProperty": EdmGuid, + "SomeInt64Property": EdmInt64} + const complexPayload = "{\"odata.metadata\": \"https://jverazsdkprim.table.core.windows.net/$metadata#testtableifprd13i\"," + "\"value\": [" + "{\"odata.etag\": \"W/\\u0022datetime\\u00272021-03-23T18%3A29%3A15.9686039Z\\u0027\\u0022\"," + diff --git a/sdk/tables/aztables/zt_tableRecordedTests.go b/sdk/tables/aztables/zt_tableRecordedTests.go index 5226744376f2..a7fd1896371d 100644 --- a/sdk/tables/aztables/zt_tableRecordedTests.go +++ b/sdk/tables/aztables/zt_tableRecordedTests.go @@ -6,7 +6,9 @@ package aztables import ( "context" "fmt" + "math" "testing" + "time" "github.com/Azure/azure-sdk-for-go/sdk/azcore" "github.com/Azure/azure-sdk-for-go/sdk/internal/testframework" @@ -18,6 +20,7 @@ type tablesRecordedTests struct{} type testContext struct { recording *testframework.Recording client *TableServiceClient + context *testframework.TestContext } const ( @@ -80,12 +83,12 @@ func recordedTestSetup(t *testing.T, testName string, endpointType EndpointType, client, err := NewTableServiceClient(uri, cred, &TableClientOptions{HTTPClient: recording, Retry: azcore.RetryOptions{MaxRetries: -1}}) assert.Nil(err) - clientsMap[testName] = &testContext{client: client, recording: recording} + clientsMap[testName] = &testContext{client: client, recording: recording, context: &context} } func recordedTestTeardown(key string) { context, ok := clientsMap[key] - if ok { + if ok && !(*context.context).IsFailed() { context.recording.Stop() } } @@ -134,3 +137,43 @@ func createSimpleEntities(count int, pk string) *[]map[string]interface{} { } return &result } + +func createComplexEntities(context *testContext, count int, pk string) *[]complexEntity { + result := make([]complexEntity, count) + + sp := "some pointer to string" + for i := 1; i <= count; i++ { + var e = complexEntity{ + PartitionKey: "partition", + ETag: "*", + RowKey: "row", + Timestamp: context.recording.Now(), + SomeBinaryProperty: []byte("some bytes"), + SomeDateProperty: context.recording.Now(), + SomeDoubleProperty0: float64(1), + SomeDoubleProperty1: float64(1.2345), + SomeGuidProperty: context.recording.UUID(), + SomeInt64Property: math.MaxInt64, + SomeIntProperty: 42, + SomeStringProperty: "some string", + SomePtrStringProperty: &sp} + result[i-1] = e + } + return &result +} + +type complexEntity struct { + ETag string + PartitionKey string + RowKey string + Timestamp time.Time + SomeBinaryProperty []byte + SomeDateProperty time.Time + SomeDoubleProperty0 float64 + SomeDoubleProperty1 float64 + SomeGuidProperty [16]byte `uuid:""` + SomeInt64Property int64 + SomeIntProperty int + SomeStringProperty string + SomePtrStringProperty *string +} From 75d334e984bf333b86447a947b6003723ecbfd17 Mon Sep 17 00:00:00 2001 From: Christopher Scott Date: Sat, 10 Apr 2021 19:26:05 -0500 Subject: [PATCH 09/18] Implement complex entity and struct entity support --- .../TestAddComplexEntity-variables.yaml | 6 + .../TestAddComplexEntity.yaml | 121 +++++++++++++++ .../TestAddComplexEntity-variables.yaml | 6 + .../TestAddComplexEntity.yaml | 139 ++++++++++++++++++ sdk/tables/aztables/tableClient_test.go | 16 +- sdk/tables/aztables/zc_table_pagers.go | 4 + sdk/tables/aztables/zc_table_pagers_test.go | 5 +- 7 files changed, 287 insertions(+), 10 deletions(-) create mode 100644 sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestAddComplexEntity-variables.yaml create mode 100644 sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestAddComplexEntity.yaml create mode 100644 sdk/tables/aztables/recordings/TestTableClient_Storage/TestAddComplexEntity-variables.yaml create mode 100644 sdk/tables/aztables/recordings/TestTableClient_Storage/TestAddComplexEntity.yaml diff --git a/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestAddComplexEntity-variables.yaml b/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestAddComplexEntity-variables.yaml new file mode 100644 index 000000000000..a5295bc78865 --- /dev/null +++ b/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestAddComplexEntity-variables.yaml @@ -0,0 +1,6 @@ +--- +COSMOS_TABLES_ENDPOINT_SUFFIX: cosmos.azure.com +TABLES_COSMOS_ACCOUNT_NAME: chrisstablesprim +TABLES_PRIMARY_COSMOS_ACCOUNT_KEY: Kg== +now: "2021-04-10T19:18:39.9706889-05:00" +randomSeed: "1618100318" diff --git a/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestAddComplexEntity.yaml b/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestAddComplexEntity.yaml new file mode 100644 index 000000000000..a90bdd2b73da --- /dev/null +++ b/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestAddComplexEntity.yaml @@ -0,0 +1,121 @@ +--- +version: 1 +interactions: +- request: + body: '{"TableName":"gotablexiw8zfw9mws0q"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "36" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 11 Apr 2021 00:18:38 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/Tables + method: POST + response: + body: '{"TableName":"gotablexiw8zfw9mws0q","odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables/@Element"}' + headers: + Content-Type: + - application/json;odata=minimalmetadata + Date: + - Sun, 11 Apr 2021 00:18:39 GMT + Etag: + - W/"datetime'2021-04-11T00%3A18%3A39.0866952Z'" + Location: + - https://chrisstablesprim.table.cosmos.azure.com/Tables('gotablexiw8zfw9mws0q') + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - 8d38468e-c994-404d-90cc-925db534f55f + status: 201 Created + code: 201 + duration: "" +- request: + body: '{"PartitionKey":"partition","RowKey":"row","SomeBinaryProperty":"c29tZSBieXRlcw==","SomeBinaryProperty@odata.type":"Edm.Binary","SomeDateProperty":"2021-04-11T00:18:39.9706889Z","SomeDateProperty@odata.type":"Edm.DateTime","SomeDoubleProperty0":1,"SomeDoubleProperty0@odata.type":"Edm.Double","SomeDoubleProperty1":1.2345,"SomeDoubleProperty1@odata.type":"Edm.Double","SomeGuidProperty":"4346b1a2-6141-483a-779b-1332da28b7d5","SomeGuidProperty@odata.type":"Edm.Guid","SomeInt64Property":"9223372036854775807","SomeInt64Property@odata.type":"Edm.Int64","SomeIntProperty":42,"SomePtrStringProperty":"some + pointer to string","SomeStringProperty":"some string"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "657" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + Prefer: + - return-no-content + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 11 Apr 2021 00:18:39 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/gotablexiw8zfw9mws0q + method: POST + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Sun, 11 Apr 2021 00:18:39 GMT + Etag: + - W/"datetime'2021-04-11T00%3A18%3A39.7189128Z'" + Location: + - https://chrisstablesprim.table.cosmos.azure.com/gotablexiw8zfw9mws0q(PartitionKey='partition',RowKey='row') + Preference-Applied: + - return-no-content + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - cec68903-00ae-4306-ae0a-5200c5f8bb60 + status: 204 No Content + code: 204 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Authorization: + - sanitized + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 11 Apr 2021 00:18:40 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.cosmos.azure.com/Tables('gotablexiw8zfw9mws0q') + method: DELETE + response: + body: "" + headers: + Content-Length: + - "0" + Date: + - Sun, 11 Apr 2021 00:18:39 GMT + Server: + - Microsoft-HTTPAPI/2.0 + X-Ms-Request-Id: + - ef2e97eb-017c-458b-be6d-9c130a33dfa6 + status: 204 No Content + code: 204 + duration: "" diff --git a/sdk/tables/aztables/recordings/TestTableClient_Storage/TestAddComplexEntity-variables.yaml b/sdk/tables/aztables/recordings/TestTableClient_Storage/TestAddComplexEntity-variables.yaml new file mode 100644 index 000000000000..f86a77d88694 --- /dev/null +++ b/sdk/tables/aztables/recordings/TestTableClient_Storage/TestAddComplexEntity-variables.yaml @@ -0,0 +1,6 @@ +--- +STORAGE_ENDPOINT_SUFFIX: core.windows.net +TABLES_PRIMARY_STORAGE_ACCOUNT_KEY: Kg== +TABLES_STORAGE_ACCOUNT_NAME: chrisstablesprim +now: "2021-04-10T19:18:38.5403201-05:00" +randomSeed: "1618100317" diff --git a/sdk/tables/aztables/recordings/TestTableClient_Storage/TestAddComplexEntity.yaml b/sdk/tables/aztables/recordings/TestTableClient_Storage/TestAddComplexEntity.yaml new file mode 100644 index 000000000000..78e8e8f28f88 --- /dev/null +++ b/sdk/tables/aztables/recordings/TestTableClient_Storage/TestAddComplexEntity.yaml @@ -0,0 +1,139 @@ +--- +version: 1 +interactions: +- request: + body: '{"TableName":"gotableseqkydnlewbop"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "36" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 11 Apr 2021 00:18:37 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/Tables + method: POST + response: + body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#Tables/@Element","TableName":"gotableseqkydnlewbop"}' + headers: + Cache-Control: + - no-cache + Content-Type: + - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 + Date: + - Sun, 11 Apr 2021 00:18:38 GMT + Location: + - https://chrisstablesprim.table.core.windows.net/Tables('gotableseqkydnlewbop') + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 91267bb0-7002-0034-4468-2e07dc000000 + X-Ms-Version: + - "2019-02-02" + status: 201 Created + code: 201 + duration: "" +- request: + body: '{"PartitionKey":"partition","RowKey":"row","SomeBinaryProperty":"c29tZSBieXRlcw==","SomeBinaryProperty@odata.type":"Edm.Binary","SomeDateProperty":"2021-04-11T00:18:38.5403201Z","SomeDateProperty@odata.type":"Edm.DateTime","SomeDoubleProperty0":1,"SomeDoubleProperty0@odata.type":"Edm.Double","SomeDoubleProperty1":1.2345,"SomeDoubleProperty1@odata.type":"Edm.Double","SomeGuidProperty":"bc08bdf6-10bd-4b3e-612f-62de19f57821","SomeGuidProperty@odata.type":"Edm.Guid","SomeInt64Property":"9223372036854775807","SomeInt64Property@odata.type":"Edm.Int64","SomeIntProperty":42,"SomePtrStringProperty":"some + pointer to string","SomeStringProperty":"some string"}' + form: {} + headers: + Accept: + - application/json;odata=minimalmetadata + Authorization: + - sanitized + Content-Length: + - "657" + Content-Type: + - application/json + Dataserviceversion: + - "3.0" + Prefer: + - return-no-content + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 11 Apr 2021 00:18:38 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/gotableseqkydnlewbop + method: POST + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Dataserviceid: + - https://chrisstablesprim.table.core.windows.net/gotableseqkydnlewbop(PartitionKey='partition',RowKey='row') + Date: + - Sun, 11 Apr 2021 00:18:38 GMT + Etag: + - W/"datetime'2021-04-11T00%3A18%3A38.2407207Z'" + Location: + - https://chrisstablesprim.table.core.windows.net/gotableseqkydnlewbop(PartitionKey='partition',RowKey='row') + Preference-Applied: + - return-no-content + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 91267bbe-7002-0034-5068-2e07dc000000 + X-Ms-Version: + - "2019-02-02" + status: 204 No Content + code: 204 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Authorization: + - sanitized + User-Agent: + - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; + Windows_NT) + X-Ms-Date: + - Sun, 11 Apr 2021 00:18:38 GMT + X-Ms-Version: + - "2019-02-02" + url: https://chrisstablesprim.table.core.windows.net/Tables('gotableseqkydnlewbop') + method: DELETE + response: + body: "" + headers: + Cache-Control: + - no-cache + Content-Length: + - "0" + Date: + - Sun, 11 Apr 2021 00:18:38 GMT + Server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + X-Content-Type-Options: + - nosniff + X-Ms-Request-Id: + - 91267bc3-7002-0034-5568-2e07dc000000 + X-Ms-Version: + - "2019-02-02" + status: 204 No Content + code: 204 + duration: "" diff --git a/sdk/tables/aztables/tableClient_test.go b/sdk/tables/aztables/tableClient_test.go index 01d18b9e0afb..5a3a666b123b 100644 --- a/sdk/tables/aztables/tableClient_test.go +++ b/sdk/tables/aztables/tableClient_test.go @@ -5,11 +5,11 @@ package aztables import ( "bytes" - "io" "io/ioutil" "net/http" "testing" + "github.com/Azure/azure-sdk-for-go/sdk/internal/runtime" "github.com/Azure/azure-sdk-for-go/sdk/internal/testframework" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" @@ -66,7 +66,7 @@ func (s *tableClientLiveTests) TestAddEntity() { } } -func (s *tableClientLiveTests) aTestAddComplexEntity() { +func (s *tableClientLiveTests) TestAddComplexEntity() { assert := assert.New(s.T()) context := getTestContext(s.T().Name()) client, delete := s.init(true) @@ -76,7 +76,7 @@ func (s *tableClientLiveTests) aTestAddComplexEntity() { for _, e := range *entitiesToCreate { _, err := client.AddEntity(ctx, &e) - assert.Nil(err) + assert.Nilf(err, getStringFromBody(err)) } } @@ -139,8 +139,7 @@ func (s *tableClientLiveTests) init(doCreate bool) (*TableClient, func()) { if doCreate { _, err := client.Create(ctx) if err != nil { - r := err.RawResponse() - assert.FailNow(r.Status) + assert.FailNow(getStringFromBody(err)) } } return client, func() { @@ -148,8 +147,13 @@ func (s *tableClientLiveTests) init(doCreate bool) (*TableClient, func()) { } } -func getStringFromBody(b io.ReadCloser) string { +func getStringFromBody(e *runtime.ResponseError) string { + if e == nil { + return "Error is nil" + } + r := e.RawResponse() body := bytes.Buffer{} + b := r.Body b.Close() if b != nil { _, err := body.ReadFrom(b) diff --git a/sdk/tables/aztables/zc_table_pagers.go b/sdk/tables/aztables/zc_table_pagers.go index d63afc82c782..e411d42f2afe 100644 --- a/sdk/tables/aztables/zc_table_pagers.go +++ b/sdk/tables/aztables/zc_table_pagers.go @@ -156,6 +156,10 @@ func toMap(ent interface{}) (*map[string]interface{}, error) { Switch: f := typeOfT.Field(i) name := f.Name + if name == ETag || name == Timestamp { + // we do not need to serialize ETag or TimeStamp + continue + } // add odata annotations for the types that require it. switch k := v.Type().Kind(); k { case reflect.Array, reflect.Map, reflect.Slice: diff --git a/sdk/tables/aztables/zc_table_pagers_test.go b/sdk/tables/aztables/zc_table_pagers_test.go index 6d44603b2918..eae76b3b0105 100644 --- a/sdk/tables/aztables/zc_table_pagers_test.go +++ b/sdk/tables/aztables/zc_table_pagers_test.go @@ -63,10 +63,8 @@ func TestToMap(t *testing.T) { // validate all the types were properly casted / converted assert.Equal(ent.PartitionKey, (*entMap)["PartitionKey"]) assert.Equal(ent.RowKey, (*entMap)["RowKey"]) - ts, _ := time.Parse(ISO8601, (*entMap)["Timestamp"].(string)) - assert.Equal(ent.Timestamp.UTC().String(), ts.String()) assert.Equal(base64.StdEncoding.EncodeToString(ent.SomeBinaryProperty), string((*entMap)["SomeBinaryProperty"].(string))) - ts, _ = time.Parse(ISO8601, (*entMap)["SomeDateProperty"].(string)) + ts, _ := time.Parse(ISO8601, (*entMap)["SomeDateProperty"].(string)) assert.Equal(ent.SomeDateProperty.UTC().String(), ts.String()) assert.Equal(ent.SomeDoubleProperty0, (*entMap)["SomeDoubleProperty0"]) assert.Equal(ent.SomeDoubleProperty1, (*entMap)["SomeDoubleProperty1"]) @@ -115,7 +113,6 @@ func closerFromString(content string) io.ReadCloser { } var odataHintProps = map[string]string{ - "Timestamp": EdmDateTime, "SomeBinaryProperty": EdmBinary, "SomeDateProperty": EdmDateTime, "SomeDoubleProperty0": EdmDouble, From a450961e3a93bb40a3927e4d5128a1e483c865cc Mon Sep 17 00:00:00 2001 From: Christopher Scott Date: Sun, 11 Apr 2021 00:47:39 -0500 Subject: [PATCH 10/18] fb --- sdk/internal/testframework/recording.go | 111 ++++++++---------- .../testframework/recording_sanitizer.go | 39 ++++-- .../testframework/recording_sanitizer_test.go | 25 ++-- sdk/internal/testframework/recording_test.go | 24 ++-- sdk/internal/testframework/testcontext.go | 8 ++ sdk/internal/uuid/uuid.go | 1 + sdk/tables/aztables/tableClient.go | 10 +- sdk/tables/aztables/zc_table_pagers_test.go | 4 +- sdk/tables/aztables/zt_tableRecordedTests.go | 12 +- 9 files changed, 131 insertions(+), 103 deletions(-) diff --git a/sdk/internal/testframework/recording.go b/sdk/internal/testframework/recording.go index 516579baadf3..890be2f22dee 100644 --- a/sdk/internal/testframework/recording.go +++ b/sdk/internal/testframework/recording.go @@ -68,11 +68,11 @@ const ( Secret_Base64String VariableType = "secret_base64String" ) +// NewRecording initializes a new Recording instance func NewRecording(c TestContext, mode RecordMode) (*Recording, error) { // create recorder based on the test name, recordMode, variables, and sanitizers recPath, varPath := getFilePaths(c.Name()) rec, err := recorder.NewAsMode(recPath, modeMap[mode], nil) - if err != nil { return nil, err } @@ -109,9 +109,9 @@ func NewRecording(c TestContext, mode RecordMode) (*Recording, error) { return recording, err } -// Gets a recorded variable. If the variable is not found we return an error -// variableType is optional and defaults to Default -func (r *Recording) GetRecordedVariable(name string, variableType ...VariableType) (*string, error) { +// GetRecordedVariable returns a recorded variable. If the variable is not found we return an error +// variableType determines how the recorded variable will be saved. Default indicates that the value should be saved without any sanitation. +func (r *Recording) GetRecordedVariable(name string, variableType VariableType) (*string, error) { var err error result, ok := r.previousSessionVariables[name] if !ok || r.Mode == Live { @@ -120,25 +120,24 @@ func (r *Recording) GetRecordedVariable(name string, variableType ...VariableTyp if err != nil { r.c.Fail(err.Error()) return nil, err - } else { - r.variables[name] = applyVariableOptions(result, variableType...) } + r.variables[name] = applyVariableOptions(result, variableType) } return result, err } -// Gets a recorded variable with a fallback default value -// variableType is optional and defaults to Default -func (r *Recording) GetOptionalRecordedVariable(name string, defaultValue string, variableType ...VariableType) string { +// GetOptionalRecordedVariable returns a recorded variable with a fallback default value +// variableType determines how the recorded variable will be saved. Default indicates that the value should be saved without any sanitation. +func (r *Recording) GetOptionalRecordedVariable(name string, defaultValue string, variableType VariableType) string { result, ok := r.previousSessionVariables[name] if !ok || r.Mode == Live { result = getOptionalEnv(name, defaultValue) - r.variables[name] = applyVariableOptions(result, variableType...) + r.variables[name] = applyVariableOptions(result, variableType) } return *result } -// To satisfy the azcore.Transport interface +// Do satisfies the azcore.Transport interface so that Recording can be used as the transport for recorded requests func (r *Recording) Do(req *http.Request) (*http.Response, error) { resp, err := r.recorder.RoundTrip(req) if err == cassette.ErrInteractionNotFound { @@ -149,7 +148,7 @@ func (r *Recording) Do(req *http.Request) (*http.Response, error) { return resp, err } -// Stops the recording and saves them, including any captured variables, to disk +// Stop stops the recording and saves them, including any captured variables, to disk func (r *Recording) Stop() error { r.recorder.Stop() @@ -194,26 +193,6 @@ func (r *Recording) Stop() error { return nil } -// Gets an environment variable by name and returns an error if it is not found -func getRequiredEnv(name string) (*string, error) { - env, ok := os.LookupEnv(name) - if ok { - return &env, nil - } else { - return nil, errors.New(envNotExistsError(name)) - } -} - -// gets an environment variable by name and returns the defaultValue if not found -func getOptionalEnv(name string, defaultValue string) *string { - env, ok := os.LookupEnv(name) - if ok { - return &env - } else { - return &defaultValue - } -} - func (r *Recording) Now() time.Time { r.initNow() @@ -226,9 +205,9 @@ func (r *Recording) UUID() uuid.UUID { return uuid.FromSource(r.src) } -// generate a recorded random alpha numeric id +// GenerateAlphaNumericID will generate a recorded random alpha numeric id // if the recording has a randomSeed already set, the value will be generated from that seed, else a new random seed will be used -func (r *Recording) GenerateAlphaNumericId(prefix string, length int, lowercaseOnly bool) (*string, error) { +func (r *Recording) GenerateAlphaNumericID(prefix string, length int, lowercaseOnly bool) (*string, error) { if length <= len(prefix) { return nil, errors.New("length must be greater than prefix") @@ -263,6 +242,26 @@ func (r *Recording) GenerateAlphaNumericId(prefix string, length int, lowercaseO return &str, nil } +// getRequiredEnv gets an environment variable by name and returns an error if it is not found +func getRequiredEnv(name string) (*string, error) { + env, ok := os.LookupEnv(name) + if ok { + return &env, nil + } else { + return nil, errors.New(envNotExistsError(name)) + } +} + +// getOptionalEnv gets an environment variable by name and returns the defaultValue if not found +func getOptionalEnv(name string, defaultValue string) *string { + env, ok := os.LookupEnv(name) + if ok { + return &env + } else { + return &defaultValue + } +} + func (r *Recording) matchRequest(req *http.Request, rec cassette.Request) bool { isMatch := compareMethods(req, rec, r.c) && compareURLs(req, rec, r.c) && @@ -281,30 +280,26 @@ func envNotExistsError(varName string) string { return "Required environment variable not set: " + varName } -// Applies the VariableType transform to the value +// applyVariableOptions applies the VariableType transform to the value // If variableType is not provided or Default, return result // If variableType is Secret_String, return SanitizedValue // If variableType isSecret_Base64String return SanitizedBase64Value -func applyVariableOptions(val *string, variableType ...VariableType) *string { +func applyVariableOptions(val *string, variableType VariableType) *string { var ret string - switch len(variableType) { - case 0: - return val + + switch variableType { + case Secret_String: + ret = SanitizedValue + return &ret + case Secret_Base64String: + ret = SanitizedBase64Value + return &ret default: - switch vt := variableType[0]; vt { - case Secret_String: - ret = SanitizedValue - return &ret - case Secret_Base64String: - ret = SanitizedBase64Value - return &ret - default: - return val - } + return val } } -// Initializes the Source to be used for random value creation in this Recording +// initRandomSource initializes the Source to be used for random value creation in this Recording func (r *Recording) initRandomSource() { // if we already have a Source generated, return immediately if r.src != nil { @@ -331,7 +326,7 @@ func (r *Recording) initRandomSource() { r.src = rand.NewSource(seed) } -// Initializes the Source to be used for random value creation in this Recording +// initNow initializes the Source to be used for random value creation in this Recording func (r *Recording) initNow() { // if we already have a now generated, return immediately if r.now != nil { @@ -360,18 +355,21 @@ func (r *Recording) initNow() { r.now = &newNow } -// returns (recordingFilePath, variablesFilePath) +// getFilePaths returns (recordingFilePath, variablesFilePath) func getFilePaths(name string) (string, string) { recPath := "recordings/" + name varPath := fmt.Sprintf("%s-variables.yaml", recPath) return recPath, varPath } -// Calls os.Create on the VariablesFile and creates it if it or the path does not exist +// createVariablesFileIfNotExists calls os.Create on the VariablesFile and creates it if it or the path does not exist // Callers must call Close on the result func (r *Recording) createVariablesFileIfNotExists() (*os.File, error) { f, err := os.Create(r.VariablesFile) if err != nil { + if !os.IsNotExist(err) { + return nil, err + } // Create directory for the variables if missing variablesDir := filepath.Dir(r.VariablesFile) if _, err := os.Stat(variablesDir); os.IsNotExist(err) { @@ -406,12 +404,7 @@ func (r *Recording) unmarshalVariablesFile(out interface{}) error { } func (r *Recording) initVariables() error { - err := r.unmarshalVariablesFile(r.previousSessionVariables) - if err != nil { - return nil - } - - return nil + return r.unmarshalVariablesFile(r.previousSessionVariables) } var modeMap = map[RecordMode]recorder.Mode{ diff --git a/sdk/internal/testframework/recording_sanitizer.go b/sdk/internal/testframework/recording_sanitizer.go index 9064da86c6f3..ac4311ef46a2 100644 --- a/sdk/internal/testframework/recording_sanitizer.go +++ b/sdk/internal/testframework/recording_sanitizer.go @@ -6,18 +6,20 @@ package testframework import ( + "net/http" + "github.com/dnaeon/go-vcr/cassette" "github.com/dnaeon/go-vcr/recorder" - "net/http" ) type RecordingSanitizer struct { recorder *recorder.Recorder headersToSanitize map[string]*string urlSanitizer StringSanitizer + bodySanitizer StringSanitizer } -type StringSanitizer func(*string) error +type StringSanitizer func(*string) const SanitizedValue string = "sanitized" const SanitizedBase64Value string = "Kg==" @@ -32,12 +34,23 @@ func DefaultSanitizer(recorder *recorder.Recorder) *RecordingSanitizer { return s } +// AddSanitizedHeaders adds the supplied header names to the list of headers to be sanitized on request and response recordings. func (s *RecordingSanitizer) AddSanitizedHeaders(headers ...string) { for _, headerName := range headers { s.headersToSanitize[headerName] = nil } } +// AddBodysanitizer configures the supplied StringSanitizer to sanitize recording request and response bodies +func (s *RecordingSanitizer) AddBodysanitizer(sanitizer StringSanitizer) { + s.bodySanitizer = sanitizer +} + +// AddUriSanitizer configures the supplied StringSanitizer to sanitize recording request and response URLs +func (s *RecordingSanitizer) AddUrlSanitizer(sanitizer StringSanitizer) { + s.urlSanitizer = sanitizer +} + func (s *RecordingSanitizer) sanitizeHeaders(header http.Header) { for headerName := range s.headersToSanitize { if _, ok := header[headerName]; ok { @@ -46,19 +59,25 @@ func (s *RecordingSanitizer) sanitizeHeaders(header http.Header) { } } -func (s *RecordingSanitizer) AddUrlSanitizer(sanitizer StringSanitizer) { - s.urlSanitizer = sanitizer +func (s *RecordingSanitizer) sanitizeBodies(body *string) { + s.bodySanitizer(body) } -func (s *RecordingSanitizer) sanitizeURL(url *string) error { - return s.urlSanitizer(url) +func (s *RecordingSanitizer) sanitizeURL(url *string) { + s.urlSanitizer(url) } func (s *RecordingSanitizer) applySaveFilter(i *cassette.Interaction) error { s.sanitizeHeaders(i.Request.Headers) - return s.sanitizeURL(&i.Request.URL) -} - -func DefaultStringSanitizer(s *string) error { + s.sanitizeHeaders(i.Response.Headers) + s.sanitizeURL(&i.Request.URL) + if len(i.Request.Body) > 0 { + s.sanitizeBodies(&i.Request.Body) + } + if len(i.Response.Body) > 0 { + s.sanitizeBodies(&i.Response.Body) + } return nil } + +func DefaultStringSanitizer(s *string) {} diff --git a/sdk/internal/testframework/recording_sanitizer_test.go b/sdk/internal/testframework/recording_sanitizer_test.go index 951897485073..570dfb3b005b 100644 --- a/sdk/internal/testframework/recording_sanitizer_test.go +++ b/sdk/internal/testframework/recording_sanitizer_test.go @@ -93,22 +93,25 @@ func (s *recordingSanitizerTests) TestAddSanitizedHeadersSanitizes() { func (s *recordingSanitizerTests) TestAddUrlSanitizerSanitizes() { assert := assert.New(s.T()) + secret := "secretvalue" + secretBody := "some body content that contains a " + secret server, cleanup := mock.NewServer() - server.SetResponse(mock.WithStatusCode(http.StatusNoContent)) + server.SetResponse(mock.WithStatusCode(http.StatusCreated), mock.WithBody([]byte(secretBody))) defer cleanup() rt := NewMockRoundTripper(server) r, _ := recorder.NewAsMode(getTestFileName(s.T(), false), recorder.ModeRecording, rt) - sanitizedUrl := server.URL() - secret := "/secretvalue" + baseUrl := server.URL() + "/" target := DefaultSanitizer(r) - target.AddUrlSanitizer(func(url *string) error { - *url = strings.Replace(*url, secret, "", -1) - return nil + target.AddUrlSanitizer(func(url *string) { + *url = strings.Replace(*url, secret, SanitizedValue, -1) + }) + target.AddBodysanitizer(func(body *string) { + *body = strings.Replace(*body, secret, SanitizedValue, -1) }) - req, _ := http.NewRequest(http.MethodPost, sanitizedUrl+secret, nil) + req, _ := http.NewRequest(http.MethodPost, baseUrl+secret, closerFromString(secretBody)) r.RoundTrip(req) r.Stop() @@ -117,8 +120,12 @@ func (s *recordingSanitizerTests) TestAddUrlSanitizerSanitizes() { assert.Nil(err) for _, i := range rec.Interactions { - assert.NotEqual(sanitizedUrl+secret, i.Request.URL) - assert.Equal(sanitizedUrl, i.Request.URL) + assert.NotContains(i.Response.Body, secret) + assert.NotContains(i.Request.URL, secret) + assert.NotContains(i.Request.Body, secret) + assert.Contains(i.Request.URL, SanitizedValue) + assert.Contains(i.Request.Body, SanitizedValue) + assert.Contains(i.Response.Body, SanitizedValue) } } diff --git a/sdk/internal/testframework/recording_test.go b/sdk/internal/testframework/recording_test.go index a008793cd304..6fbe31b1cdb7 100644 --- a/sdk/internal/testframework/recording_test.go +++ b/sdk/internal/testframework/recording_test.go @@ -70,17 +70,17 @@ func (s *recordingTests) TestRecordedVariables() { assert.Nil(err) // optional variables always succeed. - assert.Equal(expectedVariableValue, target.GetOptionalRecordedVariable(nonExistingEnvVar, expectedVariableValue)) + assert.Equal(expectedVariableValue, target.GetOptionalRecordedVariable(nonExistingEnvVar, expectedVariableValue, Default)) // non existent variables return an error - val, err := target.GetRecordedVariable(nonExistingEnvVar) + val, err := target.GetRecordedVariable(nonExistingEnvVar, Default) // mark test as succeeded assert.Equal(envNotExistsError(nonExistingEnvVar), err.Error()) // now create the env variable and check that it can be fetched os.Setenv(nonExistingEnvVar, expectedVariableValue) defer os.Unsetenv(nonExistingEnvVar) - val, err = target.GetRecordedVariable(nonExistingEnvVar) + val, err = target.GetRecordedVariable(nonExistingEnvVar, Default) assert.Equal(expectedVariableValue, *val) err = target.Stop() @@ -143,7 +143,7 @@ func (s *recordingTests) TestStopSavesVariablesIfExistAndReadsPreviousVariables( target, err := NewRecording(context, Playback) assert.Nil(err) - target.GetOptionalRecordedVariable(expectedVariableName, expectedVariableValue) + target.GetOptionalRecordedVariable(expectedVariableName, expectedVariableValue, Default) err = target.Stop() assert.Nil(err) @@ -159,7 +159,7 @@ func (s *recordingTests) TestStopSavesVariablesIfExistAndReadsPreviousVariables( assert.Nil(err) // add a new variable to the existing batch - target2.GetOptionalRecordedVariable(addedVariableName, addedVariableValue) + target2.GetOptionalRecordedVariable(addedVariableName, addedVariableValue, Default) err = target2.Stop() assert.Nil(err) @@ -229,7 +229,7 @@ func (s *recordingTests) TestNow() { assert.Nil(err) } -func (s *recordingTests) TestGenerateAlphaNumericId() { +func (s *recordingTests) TestGenerateAlphaNumericID() { assert := assert.New(s.T()) context := NewTestContext(func(msg string) { assert.FailNow(msg) }, func(msg string) { s.T().Log(msg) }, func() string { return s.T().Name() }) @@ -238,12 +238,12 @@ func (s *recordingTests) TestGenerateAlphaNumericId() { target, err := NewRecording(context, Playback) assert.Nil(err) - generated1, err := target.GenerateAlphaNumericId(prefix, 10, true) + generated1, err := target.GenerateAlphaNumericID(prefix, 10, true) assert.Equal(10, len(*generated1)) assert.Equal(true, strings.HasPrefix(*generated1, prefix)) - generated1a, err := target.GenerateAlphaNumericId(prefix, 10, true) + generated1a, err := target.GenerateAlphaNumericID(prefix, 10, true) assert.NotEqual(generated1, generated1a) err = target.Stop() @@ -252,7 +252,7 @@ func (s *recordingTests) TestGenerateAlphaNumericId() { target2, err := NewRecording(context, Playback) assert.Nil(err) - generated2, err := target2.GenerateAlphaNumericId(prefix, 10, true) + generated2, err := target2.GenerateAlphaNumericID(prefix, 10, true) // The two generated Ids should be the same since target2 loaded the saved random seed from target assert.Equal(*generated2, *generated1) @@ -272,7 +272,7 @@ func (s *recordingTests) TestRecordRequestsAndDoMatching() { target, err := NewRecording(context, Playback) target.recorder.SetTransport(rt) - path, err := target.GenerateAlphaNumericId("", 5, true) + path, err := target.GenerateAlphaNumericID("", 5, true) reqUrl := server.URL() + "/" + *path req, _ := http.NewRequest(http.MethodPost, reqUrl, nil) @@ -294,7 +294,7 @@ func (s *recordingTests) TestRecordRequestsAndDoMatching() { target.recorder.SetTransport(rt) // re-create the random url using the recorded variables - path, err = target.GenerateAlphaNumericId("", 5, true) + path, err = target.GenerateAlphaNumericID("", 5, true) reqUrl = server.URL() + "/" + *path req, _ = http.NewRequest(http.MethodPost, reqUrl, nil) @@ -315,7 +315,7 @@ func (s *recordingTests) TestRecordRequestsAndFailMatchingForMissingRecording() target, err := NewRecording(context, Playback) target.recorder.SetTransport(rt) - path, err := target.GenerateAlphaNumericId("", 5, true) + path, err := target.GenerateAlphaNumericID("", 5, true) reqUrl := server.URL() + "/" + *path req, _ := http.NewRequest(http.MethodPost, reqUrl, nil) diff --git a/sdk/internal/testframework/testcontext.go b/sdk/internal/testframework/testcontext.go index 84579d5ccf62..97bcc132e5ef 100644 --- a/sdk/internal/testframework/testcontext.go +++ b/sdk/internal/testframework/testcontext.go @@ -23,20 +23,28 @@ type Failer func(string) type Logger func(string) type Name func() string +// NewTestContext initializes a new TestContext func NewTestContext(failer Failer, logger Logger, name Name) TestContext { return &testContext{fail: failer, log: logger, name: name()} } +// Fail calls the Failer func and makes IsFailed return true. func (c *testContext) Fail(msg string) { c.failed = true c.fail(msg) } + +// Log calls the Logger func. func (c *testContext) Log(msg string) { c.log(msg) } + +// Name calls the Name func and returns the result. func (c *testContext) Name() string { return c.name } + +// IsFailed returns true if the Failer has been called. func (c *testContext) IsFailed() bool { return c.failed } diff --git a/sdk/internal/uuid/uuid.go b/sdk/internal/uuid/uuid.go index 2ed1dd7477eb..2f3c55d0e633 100644 --- a/sdk/internal/uuid/uuid.go +++ b/sdk/internal/uuid/uuid.go @@ -41,6 +41,7 @@ func New() UUID { return u } +// FromSource returns a new uuid based on the supplied rand.Source as a seed. func FromSource(src rand.Source) UUID { u := UUID{} // Set all bits to randomly (or pseudo-randomly) chosen values. diff --git a/sdk/tables/aztables/tableClient.go b/sdk/tables/aztables/tableClient.go index e20db2738a89..deb48bd5c807 100644 --- a/sdk/tables/aztables/tableClient.go +++ b/sdk/tables/aztables/tableClient.go @@ -28,22 +28,22 @@ func (t *TableClient) Name() string { return t.name } -// Creates the table with the name specified in NewTableClient +// Create creates the table with the name specified in NewTableClient func (t *TableClient) Create(ctx context.Context) (*TableResponseResponse, *runtime.ResponseError) { return t.service.Create(ctx, t.name) } -// Deletes the current table +// Delete deletes the current table func (t *TableClient) Delete(ctx context.Context) (*TableDeleteResponse, *runtime.ResponseError) { return t.service.Delete(ctx, t.name) } -// Queries the tables using the specified QueryOptions +// Query queries the tables using the specified QueryOptions func (t *TableClient) Query(queryOptions QueryOptions) TableEntityQueryResponsePager { return &tableEntityQueryResponsePager{tableClient: t, queryOptions: &queryOptions, tableQueryOptions: &TableQueryEntitiesOptions{}} } -// Creates an entity +// AddMapEntity Creates an entity from a map value. func (t *TableClient) AddMapEntity(ctx context.Context, entity *map[string]interface{}) (*TableInsertEntityResponse, *runtime.ResponseError) { resp, err := t.client.InsertEntity(ctx, t.name, &TableInsertEntityOptions{TableEntityProperties: entity, ResponsePreference: ResponseFormatReturnNoContent.ToPtr()}, &QueryOptions{}) if err == nil { @@ -54,7 +54,7 @@ func (t *TableClient) AddMapEntity(ctx context.Context, entity *map[string]inter } } -// Creates an entity +// AddEntity creates an entity from an arbitrary struct value. func (t *TableClient) AddEntity(ctx context.Context, entity interface{}) (*TableInsertEntityResponse, *runtime.ResponseError) { entmap, err := toMap(entity) if err != nil { diff --git a/sdk/tables/aztables/zc_table_pagers_test.go b/sdk/tables/aztables/zc_table_pagers_test.go index eae76b3b0105..d9c5f3535249 100644 --- a/sdk/tables/aztables/zc_table_pagers_test.go +++ b/sdk/tables/aztables/zc_table_pagers_test.go @@ -34,7 +34,7 @@ func TestCastAndRemoveAnnotations(t *testing.T) { entity, err := castAndRemoveAnnotations(&val) assert.Nil(err) // assert all odata annotations are removed. - for k, _ := range *entity { + for k := range *entity { assert.NotContains(k, OdataType) } @@ -65,7 +65,7 @@ func TestToMap(t *testing.T) { assert.Equal(ent.RowKey, (*entMap)["RowKey"]) assert.Equal(base64.StdEncoding.EncodeToString(ent.SomeBinaryProperty), string((*entMap)["SomeBinaryProperty"].(string))) ts, _ := time.Parse(ISO8601, (*entMap)["SomeDateProperty"].(string)) - assert.Equal(ent.SomeDateProperty.UTC().String(), ts.String()) + assert.Equal(ent.SomeDateProperty.UTC().Format(ISO8601), ts.Format(ISO8601)) assert.Equal(ent.SomeDoubleProperty0, (*entMap)["SomeDoubleProperty0"]) assert.Equal(ent.SomeDoubleProperty1, (*entMap)["SomeDoubleProperty1"]) var u uuid.UUID = ent.SomeGuidProperty diff --git a/sdk/tables/aztables/zt_tableRecordedTests.go b/sdk/tables/aztables/zt_tableRecordedTests.go index a7fd1896371d..456bfc11b98d 100644 --- a/sdk/tables/aztables/zt_tableRecordedTests.go +++ b/sdk/tables/aztables/zt_tableRecordedTests.go @@ -68,14 +68,14 @@ func recordedTestSetup(t *testing.T, testName string, endpointType EndpointType, assert.Nil(err) if endpointType == StorageEndpoint { - accountName, err = recording.GetRecordedVariable(storageAccountNameEnvVar) - suffix = recording.GetOptionalRecordedVariable(storageEndpointSuffixEnvVar, DefaultStorageSuffix) + accountName, err = recording.GetRecordedVariable(storageAccountNameEnvVar, testframework.Default) + suffix = recording.GetOptionalRecordedVariable(storageEndpointSuffixEnvVar, DefaultStorageSuffix, testframework.Default) secret, err = recording.GetRecordedVariable(storageAccountKeyEnvVar, testframework.Secret_Base64String) cred, _ = NewSharedKeyCredential(*accountName, *secret) uri = storageURI(*accountName, suffix) } else { - accountName, err = recording.GetRecordedVariable(cosmosAccountNameEnnVar) - suffix = recording.GetOptionalRecordedVariable(cosmosEndpointSuffixEnvVar, DefaultCosmosSuffix) + accountName, err = recording.GetRecordedVariable(cosmosAccountNameEnnVar, testframework.Default) + suffix = recording.GetOptionalRecordedVariable(cosmosEndpointSuffixEnvVar, DefaultCosmosSuffix, testframework.Default) secret, err = recording.GetRecordedVariable(cosmosAccountKeyEnvVar, testframework.Secret_Base64String) cred, _ = NewSharedKeyCredential(*accountName, *secret) uri = cosmosURI(*accountName, suffix) @@ -116,9 +116,9 @@ func getTestContext(key string) *testContext { func getTableName(context *testContext, prefix ...string) (*string, error) { if len(prefix) == 0 { - return context.recording.GenerateAlphaNumericId(tableNamePrefix, 20, true) + return context.recording.GenerateAlphaNumericID(tableNamePrefix, 20, true) } else { - return context.recording.GenerateAlphaNumericId(prefix[0], 20, true) + return context.recording.GenerateAlphaNumericID(prefix[0], 20, true) } } From dccd334b697cbc5e5b540d53564357dc253bf62e Mon Sep 17 00:00:00 2001 From: Christopher Scott Date: Mon, 12 Apr 2021 13:40:38 -0500 Subject: [PATCH 11/18] delete unused file --- sdk/tables/aztables/tableUUID.go | 34 -------------------------------- 1 file changed, 34 deletions(-) delete mode 100644 sdk/tables/aztables/tableUUID.go diff --git a/sdk/tables/aztables/tableUUID.go b/sdk/tables/aztables/tableUUID.go deleted file mode 100644 index bc1fc0e83cf0..000000000000 --- a/sdk/tables/aztables/tableUUID.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -package aztables - -import ( - "github.com/Azure/azure-sdk-for-go/sdk/internal/uuid" -) - -// UUID is a struct wrapper around the github.com/Azure/azure-sdk-for-go/sdk/internal/uuid type. -// This wrapper type assists in the proper serialization of uuid types to the Table service. -type UUID struct { - u uuid.UUID -} - -// New returns a new uuid using RFC 4122 algorithm. -func NewTableUUID() UUID { - return UUID{u: uuid.New()} -} - -// String returns an unparsed version of the generated UUID sequence. -func (u UUID) String() string { - return u.String() -} - -// Parse parses a string formatted as "003020100-0504-0706-0809-0a0b0c0d0e0f" -// or "{03020100-0504-0706-0809-0a0b0c0d0e0f}" into a UUID. -func Parse(uuidStr string) UUID { - return UUID{uuid.Parse(uuidStr)} -} - -func (u UUID) bytes() []byte { - return u.u[:] -} From 7cb0839cef8dc0108143d44292cf570bc870fd3c Mon Sep 17 00:00:00 2001 From: Christopher Scott Date: Fri, 16 Apr 2021 09:04:37 -0500 Subject: [PATCH 12/18] remove pointer return from GetRecordedVariable --- sdk/internal/testframework/recording.go | 6 +++--- sdk/internal/testframework/recording_test.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sdk/internal/testframework/recording.go b/sdk/internal/testframework/recording.go index 890be2f22dee..f40083f10115 100644 --- a/sdk/internal/testframework/recording.go +++ b/sdk/internal/testframework/recording.go @@ -111,7 +111,7 @@ func NewRecording(c TestContext, mode RecordMode) (*Recording, error) { // GetRecordedVariable returns a recorded variable. If the variable is not found we return an error // variableType determines how the recorded variable will be saved. Default indicates that the value should be saved without any sanitation. -func (r *Recording) GetRecordedVariable(name string, variableType VariableType) (*string, error) { +func (r *Recording) GetRecordedVariable(name string, variableType VariableType) (string, error) { var err error result, ok := r.previousSessionVariables[name] if !ok || r.Mode == Live { @@ -119,11 +119,11 @@ func (r *Recording) GetRecordedVariable(name string, variableType VariableType) result, err = getRequiredEnv(name) if err != nil { r.c.Fail(err.Error()) - return nil, err + return "", err } r.variables[name] = applyVariableOptions(result, variableType) } - return result, err + return *result, err } // GetOptionalRecordedVariable returns a recorded variable with a fallback default value diff --git a/sdk/internal/testframework/recording_test.go b/sdk/internal/testframework/recording_test.go index 6fbe31b1cdb7..04cdd23e28cf 100644 --- a/sdk/internal/testframework/recording_test.go +++ b/sdk/internal/testframework/recording_test.go @@ -81,7 +81,7 @@ func (s *recordingTests) TestRecordedVariables() { os.Setenv(nonExistingEnvVar, expectedVariableValue) defer os.Unsetenv(nonExistingEnvVar) val, err = target.GetRecordedVariable(nonExistingEnvVar, Default) - assert.Equal(expectedVariableValue, *val) + assert.Equal(expectedVariableValue, val) err = target.Stop() assert.Nil(err) From 8741ec6b13e3041fd3a83bce281bb7336c884f33 Mon Sep 17 00:00:00 2001 From: Christopher Scott Date: Fri, 16 Apr 2021 09:06:41 -0500 Subject: [PATCH 13/18] remove pointer return from GetRecordedVariable in aztables --- sdk/tables/aztables/zt_tableRecordedTests.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sdk/tables/aztables/zt_tableRecordedTests.go b/sdk/tables/aztables/zt_tableRecordedTests.go index 456bfc11b98d..62e0f9ffd74e 100644 --- a/sdk/tables/aztables/zt_tableRecordedTests.go +++ b/sdk/tables/aztables/zt_tableRecordedTests.go @@ -55,10 +55,10 @@ func cosmosURI(accountName string, endpointSuffix string) string { // create the test specific TableClient and wire it up to recordings func recordedTestSetup(t *testing.T, testName string, endpointType EndpointType, mode testframework.RecordMode) { - var accountName *string + var accountName string var suffix string var cred *SharedKeyCredential - var secret *string + var secret string var uri string assert := assert.New(t) @@ -71,14 +71,14 @@ func recordedTestSetup(t *testing.T, testName string, endpointType EndpointType, accountName, err = recording.GetRecordedVariable(storageAccountNameEnvVar, testframework.Default) suffix = recording.GetOptionalRecordedVariable(storageEndpointSuffixEnvVar, DefaultStorageSuffix, testframework.Default) secret, err = recording.GetRecordedVariable(storageAccountKeyEnvVar, testframework.Secret_Base64String) - cred, _ = NewSharedKeyCredential(*accountName, *secret) - uri = storageURI(*accountName, suffix) + cred, _ = NewSharedKeyCredential(accountName, secret) + uri = storageURI(accountName, suffix) } else { accountName, err = recording.GetRecordedVariable(cosmosAccountNameEnnVar, testframework.Default) suffix = recording.GetOptionalRecordedVariable(cosmosEndpointSuffixEnvVar, DefaultCosmosSuffix, testframework.Default) secret, err = recording.GetRecordedVariable(cosmosAccountKeyEnvVar, testframework.Secret_Base64String) - cred, _ = NewSharedKeyCredential(*accountName, *secret) - uri = cosmosURI(*accountName, suffix) + cred, _ = NewSharedKeyCredential(accountName, secret) + uri = cosmosURI(accountName, suffix) } client, err := NewTableServiceClient(uri, cred, &TableClientOptions{HTTPClient: recording, Retry: azcore.RetryOptions{MaxRetries: -1}}) From decb90920adf7885ed9f9bb57ecacdf485f1404e Mon Sep 17 00:00:00 2001 From: Christopher Scott Date: Sun, 18 Apr 2021 21:09:51 -0500 Subject: [PATCH 14/18] to/from map and structs --- sdk/tables/aztables/tableClient.go | 4 + sdk/tables/aztables/zc_table_pagers.go | 243 +++++++++++++++++++- sdk/tables/aztables/zc_table_pagers_test.go | 150 ++++++++++-- 3 files changed, 363 insertions(+), 34 deletions(-) diff --git a/sdk/tables/aztables/tableClient.go b/sdk/tables/aztables/tableClient.go index deb48bd5c807..6f253d6f0767 100644 --- a/sdk/tables/aztables/tableClient.go +++ b/sdk/tables/aztables/tableClient.go @@ -43,6 +43,10 @@ func (t *TableClient) Query(queryOptions QueryOptions) TableEntityQueryResponseP return &tableEntityQueryResponsePager{tableClient: t, queryOptions: &queryOptions, tableQueryOptions: &TableQueryEntitiesOptions{}} } +func (t *TableClient) QueryAsStruct(opt QueryOptions, s FromMapper) StructEntityQueryResponsePager { + return &structQueryResponsePager{mapper: s, tableClient: t, queryOptions: &opt, tableQueryOptions: &TableQueryEntitiesOptions{}} +} + // AddMapEntity Creates an entity from a map value. func (t *TableClient) AddMapEntity(ctx context.Context, entity *map[string]interface{}) (*TableInsertEntityResponse, *runtime.ResponseError) { resp, err := t.client.InsertEntity(ctx, t.name, &TableInsertEntityOptions{TableEntityProperties: entity, ResponsePreference: ResponseFormatReturnNoContent.ToPtr()}, &QueryOptions{}) diff --git a/sdk/tables/aztables/zc_table_pagers.go b/sdk/tables/aztables/zc_table_pagers.go index e411d42f2afe..1f6a11afe647 100644 --- a/sdk/tables/aztables/zc_table_pagers.go +++ b/sdk/tables/aztables/zc_table_pagers.go @@ -8,6 +8,7 @@ import ( "encoding/base64" "errors" "fmt" + "net/http" "reflect" "strconv" "strings" @@ -29,6 +30,49 @@ type TableEntityQueryResponsePager interface { Err() error } +type StructEntityQueryResponsePager interface { + NextPage(context.Context) bool + PageResponse() StructQueryResponseResponse + Err() error +} + +type StructQueryResponseResponse struct { + // ClientRequestID contains the information returned from the x-ms-client-request-id header response. + ClientRequestID *string + + // Date contains the information returned from the Date header response. + Date *time.Time + + // ETag contains the information returned from the ETag header response. + ETag *string + + // RawResponse contains the underlying HTTP response. + RawResponse *http.Response + + // RequestID contains the information returned from the x-ms-request-id header response. + RequestID *string + + // The properties for the table entity query response. + StructQueryResponse *StructQueryResponse + + // Version contains the information returned from the x-ms-version header response. + Version *string + + // XMSContinuationNextPartitionKey contains the information returned from the x-ms-continuation-NextPartitionKey header response. + XMSContinuationNextPartitionKey *string + + // XMSContinuationNextRowKey contains the information returned from the x-ms-continuation-NextRowKey header response. + XMSContinuationNextRowKey *string +} + +type StructQueryResponse struct { + // The metadata response of the table. + OdataMetadata *string `json:"odata.metadata,omitempty"` + + // List of table entities. + Value *[]interface{} `json:"value,omitempty"` +} + type tableEntityQueryResponsePager struct { tableClient *TableClient current *TableEntityQueryResponseResponse @@ -43,6 +87,7 @@ func (p *tableEntityQueryResponsePager) NextPage(ctx context.Context) bool { } var resp TableEntityQueryResponseResponse resp, p.err = p.tableClient.client.QueryEntities(ctx, p.tableClient.name, p.tableQueryOptions, p.queryOptions) + castAndRemoveAnnotationsSlice(resp.TableEntityQueryResponse.Value) p.current = &resp p.tableQueryOptions.NextPartitionKey = resp.XMSContinuationNextPartitionKey p.tableQueryOptions.NextRowKey = resp.XMSContinuationNextRowKey @@ -57,6 +102,41 @@ func (p *tableEntityQueryResponsePager) Err() error { return p.err } +type structQueryResponsePager struct { + mapper FromMapper + tableClient *TableClient + current *StructQueryResponseResponse + tableQueryOptions *TableQueryEntitiesOptions + queryOptions *QueryOptions + err error +} + +func (p *structQueryResponsePager) NextPage(ctx context.Context) bool { + if p.err != nil || (p.current != nil && p.current.XMSContinuationNextPartitionKey == nil && p.current.XMSContinuationNextRowKey == nil) { + return false + } + var resp TableEntityQueryResponseResponse + resp, p.err = p.tableClient.client.QueryEntities(ctx, p.tableClient.name, p.tableQueryOptions, p.queryOptions) + castAndRemoveAnnotationsSlice(resp.TableEntityQueryResponse.Value) + //p.current = &resp + r := make([]interface{}, 0, len(*resp.TableEntityQueryResponse.Value)) + for _, e := range *resp.TableEntityQueryResponse.Value { + r = append(r, p.mapper.FromMap(&e)) + } + p.current = &StructQueryResponseResponse{StructQueryResponse: &StructQueryResponse{Value: &r}} + p.tableQueryOptions.NextPartitionKey = resp.XMSContinuationNextPartitionKey + p.tableQueryOptions.NextRowKey = resp.XMSContinuationNextRowKey + return p.err == nil && resp.TableEntityQueryResponse.Value != nil && len(*resp.TableEntityQueryResponse.Value) > 0 +} + +func (p *structQueryResponsePager) PageResponse() StructQueryResponseResponse { + return *p.current +} + +func (p *structQueryResponsePager) Err() error { + return p.err +} + // Pager for Table Queries type TableQueryResponsePager interface { // NextPage returns true if the pager advanced to the next page. @@ -70,6 +150,10 @@ type TableQueryResponsePager interface { Err() error } +type FromMapper interface { + FromMap(e *map[string]interface{}) interface{} +} + type tableQueryResponsePager struct { client *tableClient current *TableQueryResponseResponse @@ -98,13 +182,16 @@ func (p *tableQueryResponsePager) Err() error { } func castAndRemoveAnnotationsSlice(entities *[]map[string]interface{}) { - + for _, e := range *entities { + castAndRemoveAnnotations(&e) + } } // TODO: The default behavior of json.Unmarshal is to deserialize all json numbers as Float64. // This can be a problem for table entities which store float and int differently -func castAndRemoveAnnotations(entity *map[string]interface{}) (*map[string]interface{}, error) { - value := (*entity)["value"].([]interface{})[0].(map[string]interface{}) +func castAndRemoveAnnotations(entity *map[string]interface{}) error { + //value := (*entity)["value"].([]interface{})[0].(map[string]interface{}) + value := *entity for k, v := range value { iSuffix := strings.Index(k, OdataType) @@ -120,7 +207,7 @@ func castAndRemoveAnnotations(entity *map[string]interface{}) (*map[string]inter case EdmDateTime: t, err := time.Parse(ISO8601, valAsString) if err != nil { - return nil, err + return err } value[valueKey] = t case EdmGuid: @@ -128,21 +215,69 @@ func castAndRemoveAnnotations(entity *map[string]interface{}) (*map[string]inter case EdmInt64: i, err := strconv.ParseInt(valAsString, 10, 64) if err != nil { - return nil, err + return err } value[valueKey] = i default: - return nil, errors.New(fmt.Sprintf("unsupported annotation found: %s", k)) + return errors.New(fmt.Sprintf("unsupported annotation found: %s", k)) } // remove the annotation key delete(value, k) } } - return &value, nil + return nil +} + +func toOdataAnnotatedDictionary(entity *map[string]interface{}) error { + entMap := *entity + for k, v := range entMap { + t := reflect.TypeOf(v) + Switch: + switch t.Kind() { + case reflect.Slice, reflect.Array: + if GetTypeArray(v) != reflect.TypeOf(byte(0)) { + return errors.New("arrays and slices must be of type byte") + } + // check if this is a uuid + uuidVal, ok := v.(uuid.UUID) + if ok { + entMap[k] = uuidVal.String() + entMap[odataType(k)] = EdmGuid + } else { + entMap[odataType(k)] = EdmBinary + b := v.([]byte) + entMap[k] = base64.StdEncoding.EncodeToString(b) + } + case reflect.Struct: + switch tn := reflect.TypeOf(v).String(); tn { + case "time.Time": + entMap[odataType(k)] = EdmDateTime + time := v.(time.Time) + entMap[k] = time.UTC().Format(ISO8601) + continue + default: + return errors.New(fmt.Sprintf("Invalid struct for entity field '%s' of type '%s'", k, tn)) + } + case reflect.Float32, reflect.Float64: + entMap[odataType(k)] = EdmDouble + case reflect.Int64: + entMap[odataType(k)] = EdmInt64 + i64 := v.(int64) + entMap[k] = strconv.FormatInt(i64, 10) + case reflect.Ptr: + if v == nil { + // if the pointer is nil, ignore it. + continue + } + // follow the pointer to the type and re-run the switch + t = reflect.ValueOf(v).Elem().Type() + goto Switch + } + } + return nil } func toMap(ent interface{}) (*map[string]interface{}, error) { - entMap := make(map[string]interface{}) var s reflect.Value if reflect.ValueOf(ent).Kind() == reflect.Ptr { s = reflect.ValueOf(ent).Elem() @@ -150,8 +285,10 @@ func toMap(ent interface{}) (*map[string]interface{}, error) { s = reflect.ValueOf(&ent).Elem().Elem() } typeOfT := s.Type() + nf := s.NumField() + entMap := make(map[string]interface{}, nf) - for i := 0; i < s.NumField(); i++ { + for i := 0; i < nf; i++ { v := s.Field(i) Switch: f := typeOfT.Field(i) @@ -162,7 +299,7 @@ func toMap(ent interface{}) (*map[string]interface{}, error) { } // add odata annotations for the types that require it. switch k := v.Type().Kind(); k { - case reflect.Array, reflect.Map, reflect.Slice: + case reflect.Array, reflect.Slice: if GetTypeArray(v.Interface()) != reflect.TypeOf(byte(0)) { return nil, errors.New("arrays and slices must be of type byte") } @@ -212,8 +349,92 @@ func toMap(ent interface{}) (*map[string]interface{}, error) { return &entMap, nil } +func fromMap(src interface{}, fmap *map[string]int, m *map[string]interface{}) (interface{}, error) { + tt := reflect.TypeOf(src) + srcVal := reflect.New(tt).Elem() + + for k, v := range *m { + // skip if this is an OData type descriptor + iSuffix := strings.Index(k, OdataType) + if iSuffix > 0 { + continue + } + // fetch the Field index by property name from the field map + fIndex := (*fmap)[k] + // Get the Value for the Field + val := srcVal.Field(fIndex) + Switch: + switch val.Kind() { + case reflect.String: + val.SetString(v.(string)) + case reflect.Float64: + val.SetFloat(v.(float64)) + case reflect.Int: + val.SetInt(int64(v.(float64))) + case reflect.Int64: + i64, err := strconv.ParseInt(v.(string), 10, 64) + if err != nil { + return nil, err + } + val.SetInt(i64) + case reflect.Struct: + switch tn := val.Type().String(); tn { + case "time.Time": + t, err := time.Parse(ISO8601, v.(string)) + if err != nil { + return nil, err + } + val.Set(reflect.ValueOf(t)) + } + case reflect.Ptr: + if val.IsNil() { + // populate the nil pointer with it's element type and re-run the type evaluation + val.Set(reflect.New(val.Type().Elem())) + val = val.Elem() + goto Switch + } + case reflect.Array, reflect.Map, reflect.Slice: + if GetTypeArray(val.Interface()) != reflect.TypeOf(byte(0)) { + return nil, errors.New("arrays and slices must be of type byte") + } + // // check if this is a uuid field as decorated by a tag + if _, ok := tt.Field(fIndex).Tag.Lookup("uuid"); ok { + u := uuid.Parse(v.(string)) + val.Set(reflect.ValueOf(u)) + } else { + b, err := base64.StdEncoding.DecodeString(v.(string)) + if err != nil { + return nil, err + } + val.SetBytes(b) + } + } + } + return srcVal.Interface(), nil +} + +// getTypeValueMap - builds a map of Field names to their Field index for the given interface{} +func getTypeValueMap(i interface{}) *map[string]int { + tt := reflect.TypeOf(complexEntity{}) + nf := tt.NumField() + fmap := make(map[string]int) + // build a map of field types + for i := 0; i < nf; i++ { + f := tt.Field(i) + fmap[f.Name] = i + if f.Name == ETag { + fmap[EtagOdata] = i + } + } + return &fmap +} + func odataType(n string) string { - return fmt.Sprintf("%s%s", n, OdataType) + var b strings.Builder + b.Grow(len(n) + len(OdataType)) + b.WriteString(n) + b.WriteString(OdataType) + return b.String() } func GetTypeArray(arr interface{}) reflect.Type { diff --git a/sdk/tables/aztables/zc_table_pagers_test.go b/sdk/tables/aztables/zc_table_pagers_test.go index d9c5f3535249..44a3eb99fb47 100644 --- a/sdk/tables/aztables/zc_table_pagers_test.go +++ b/sdk/tables/aztables/zc_table_pagers_test.go @@ -6,6 +6,7 @@ package aztables import ( "encoding/base64" "encoding/json" + "fmt" "io" "io/ioutil" "math" @@ -31,20 +32,86 @@ func TestCastAndRemoveAnnotations(t *testing.T) { var val map[string]interface{} err := resp.UnmarshalAsJSON(&val) assert.Nil(err) - entity, err := castAndRemoveAnnotations(&val) + err = castAndRemoveAnnotations(&val) assert.Nil(err) // assert all odata annotations are removed. - for k := range *entity { + for k := range val { assert.NotContains(k, OdataType) } - assert.IsType(time.Now(), (*entity)["SomeDateProperty"]) - assert.IsType([]byte{}, (*entity)["SomeBinaryProperty"]) - assert.IsType(float64(0), (*entity)["SomeDoubleProperty0"]) + assert.IsType(time.Now(), val["SomeDateProperty"]) + assert.IsType([]byte{}, val["SomeBinaryProperty"]) + assert.IsType(float64(0), val["SomeDoubleProperty0"]) // TODO: fix this // assert.IsType(int(0), (*entity)["SomeIntProperty"]) } +func TestToOdataAnnotatedDictionary(t *testing.T) { + assert := assert.New(t) + + var val = createComplexEntityMap() + err := toOdataAnnotatedDictionary(&val) + assert.Nil(err) + // assert all odata annotations are removed. + for k := range odataHintProps { + _, ok := val[k] + assert.Truef(ok, fmt.Sprintf("map does not contain %s", k)) + iSuffix := strings.Index(k, OdataType) + if iSuffix > 0 { + // Get the name of the property that this odataType key describes. + valueKey := k[0:iSuffix] + if !strings.Contains(valueKey, "SomeDoubleProperty") { + assert.IsTypef("", val[valueKey], fmt.Sprintf("should be type string %s", valueKey)) + } + } + _, ok = val[odataType(k)] + assert.Truef(ok, fmt.Sprintf("map does not contain %s", odataType(k))) + } +} + +func BenchmarkUnMarshal_AsJson_CastAndRemove_Map(b *testing.B) { + assert := assert.New(b) + b.ReportAllocs() + bt := []byte(complexPayload) + for i := 0; i < b.N; i++ { + var val = make(map[string]interface{}) + json.Unmarshal(bt, &val) + castAndRemoveAnnotations(&val) + assert.Equal("somePartition", val["PartitionKey"]) + } +} + +func BenchmarkUnMarshal_FromMap_Entity(b *testing.B) { + assert := assert.New(b) + fmap := getTypeValueMap(complexEntity{}) + bt := []byte(complexPayload) + for i := 0; i < b.N; i++ { + var val = make(map[string]interface{}) + json.Unmarshal(bt, &val) + result, err := fromMap(complexEntity{}, fmap, &val) + assert.Nil(err) + ent := result.(complexEntity) + assert.Equal("somePartition", ent.PartitionKey) + } +} + +func BenchmarkMarshal_Entity_ToMap_ToOdataDict_Map(b *testing.B) { + ent := createComplexEntity() + for i := 0; i < b.N; i++ { + m, _ := toMap(ent) + toOdataAnnotatedDictionary(m) + json.Marshal(m) + } +} + +func BenchmarkMarshal_Map_ToOdataDict_Map(b *testing.B) { + ent := createComplexEntityMap() + for i := 0; i < b.N; i++ { + toOdataAnnotatedDictionary(&ent) + json.Marshal(ent) + } +} + func TestToMap(t *testing.T) { assert := assert.New(t) @@ -89,25 +156,63 @@ func TestEntitySerialization(t *testing.T) { assert.NotEmpty(s) } +func TestDeserializeFromMap(t *testing.T) { + assert := assert.New(t) + + expected := createComplexEntity() + bt := []byte(complexPayload) + var val = make(map[string]interface{}) + json.Unmarshal(bt, &val) + result, err := fromMap(complexEntity{}, getTypeValueMap(complexEntity{}), &val) + assert.Nil(err) + ent := result.(complexEntity) + assert.EqualValues(expected, ent) +} + func createComplexEntity() complexEntity { sp := "some pointer to string" + t, _ := time.Parse(ISO8601, "2021-03-23T18:29:15.9686039Z") + t2, _ := time.Parse(ISO8601, "2020-01-01T01:02:00Z") + b, _ := base64.StdEncoding.DecodeString("AQIDBAU=") var e = complexEntity{ - PartitionKey: "partition", - ETag: "*", - RowKey: "row", - Timestamp: time.Now(), - SomeBinaryProperty: []byte("some bytes"), - SomeDateProperty: time.Now(), - SomeDoubleProperty0: float64(1), - SomeDoubleProperty1: float64(1.2345), - SomeGuidProperty: uuid.New(), - SomeInt64Property: math.MaxInt64, + PartitionKey: "somePartition", + ETag: "W/\"datetime'2021-04-05T05%3A02%3A40.7371784Z'\"", + RowKey: "01", + Timestamp: t, + SomeBinaryProperty: b, + SomeDateProperty: t2, + SomeDoubleProperty0: float64(1.0), + SomeDoubleProperty1: float64(1.5), + SomeGuidProperty: uuid.Parse("0d391d16-97f1-4b9a-be68-4cc871f90001"), + SomeInt64Property: int64(math.MaxInt64), SomeIntProperty: 42, - SomeStringProperty: "some string", + SomeStringProperty: "This is table entity number 01", SomePtrStringProperty: &sp} return e } +func createComplexEntityMap() map[string]interface{} { + sp := "some pointer to string" + t, _ := time.Parse(ISO8601, "2021-03-23T18:29:15.9686039Z") + t2, _ := time.Parse(ISO8601, "2020-01-01T01:02:00Z") + b, _ := base64.StdEncoding.DecodeString("AQIDBAU=") + var e = map[string]interface{}{ + "PartitionKey": "somePartition", + "ETag": "W/\"datetime'2021-04-05T05%3A02%3A40.7371784Z'\"", + "RowKey": "01", + "Timestamp": t, + "SomeBinaryProperty": b, + "SomeDateProperty": t2, + "SomeDoubleProperty0": float64(1.0), + "SomeDoubleProperty1": float64(1.5), + "SomeGuidProperty": uuid.Parse("0d391d16-97f1-4b9a-be68-4cc871f90001"), + "SomeInt64Property": int64(math.MaxInt64), + "SomeIntProperty": 42, + "SomeStringProperty": "This is table entity number 01", + "SomePtrStringProperty": &sp} + return e +} + func closerFromString(content string) io.ReadCloser { return ioutil.NopCloser(strings.NewReader(content)) } @@ -120,10 +225,8 @@ var odataHintProps = map[string]string{ "SomeGuidProperty": EdmGuid, "SomeInt64Property": EdmInt64} -const complexPayload = "{\"odata.metadata\": \"https://jverazsdkprim.table.core.windows.net/$metadata#testtableifprd13i\"," + - "\"value\": [" + - "{\"odata.etag\": \"W/\\u0022datetime\\u00272021-03-23T18%3A29%3A15.9686039Z\\u0027\\u0022\"," + - "\"PartitionKey\": \"somPartition\"," + +var complexPayload = "{\"odata.etag\": \"W/\\\"datetime'2021-04-05T05%3A02%3A40.7371784Z'\\\"\"," + + "\"PartitionKey\": \"somePartition\"," + "\"RowKey\": \"01\"," + "\"Timestamp\": \"2021-03-23T18:29:15.9686039Z\"," + "\"SomeBinaryProperty@odata.type\": \"Edm.Binary\"," + @@ -135,6 +238,7 @@ const complexPayload = "{\"odata.metadata\": \"https://jverazsdkprim.table.core. "\"SomeGuidProperty@odata.type\": \"Edm.Guid\"," + "\"SomeGuidProperty\": \"0d391d16-97f1-4b9a-be68-4cc871f90001\"," + "\"SomeInt64Property@odata.type\": \"Edm.Int64\"," + - "\"SomeInt64Property\": \"1\"," + - "\"SomeIntProperty\": 1," + - "\"SomeStringProperty\": \"This is table entity number 01\" }] }" + "\"SomeInt64Property\": \"" + strconv.FormatInt(math.MaxInt64, 10) + "\"," + + "\"SomeIntProperty\": 42," + + "\"SomeStringProperty\": \"This is table entity number 01\"," + + "\"SomePtrStringProperty\": \"some pointer to string\" }" From 05b25f42acadaec700c4ddbd421d1ceda511afa8 Mon Sep 17 00:00:00 2001 From: Christopher Scott Date: Mon, 19 Apr 2021 22:24:26 -0500 Subject: [PATCH 15/18] merge --- sdk/internal/testframework/recording.go | 6 +++--- sdk/internal/testframework/recording_test.go | 12 ++++++------ sdk/tables/aztables/tableClient_test.go | 2 +- sdk/tables/aztables/tableServiceClient_test.go | 16 ++++++++-------- sdk/tables/aztables/zt_tableRecordedTests.go | 2 +- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/sdk/internal/testframework/recording.go b/sdk/internal/testframework/recording.go index f40083f10115..0f1462812c59 100644 --- a/sdk/internal/testframework/recording.go +++ b/sdk/internal/testframework/recording.go @@ -207,10 +207,10 @@ func (r *Recording) UUID() uuid.UUID { // GenerateAlphaNumericID will generate a recorded random alpha numeric id // if the recording has a randomSeed already set, the value will be generated from that seed, else a new random seed will be used -func (r *Recording) GenerateAlphaNumericID(prefix string, length int, lowercaseOnly bool) (*string, error) { +func (r *Recording) GenerateAlphaNumericID(prefix string, length int, lowercaseOnly bool) (string, error) { if length <= len(prefix) { - return nil, errors.New("length must be greater than prefix") + return "", errors.New("length must be greater than prefix") } r.initRandomSource() @@ -239,7 +239,7 @@ func (r *Recording) GenerateAlphaNumericID(prefix string, length int, lowercaseO remain-- } str := sb.String() - return &str, nil + return str, nil } // getRequiredEnv gets an environment variable by name and returns an error if it is not found diff --git a/sdk/internal/testframework/recording_test.go b/sdk/internal/testframework/recording_test.go index 04cdd23e28cf..4ed73f5805ce 100644 --- a/sdk/internal/testframework/recording_test.go +++ b/sdk/internal/testframework/recording_test.go @@ -240,8 +240,8 @@ func (s *recordingTests) TestGenerateAlphaNumericID() { generated1, err := target.GenerateAlphaNumericID(prefix, 10, true) - assert.Equal(10, len(*generated1)) - assert.Equal(true, strings.HasPrefix(*generated1, prefix)) + assert.Equal(10, len(generated1)) + assert.Equal(true, strings.HasPrefix(generated1, prefix)) generated1a, err := target.GenerateAlphaNumericID(prefix, 10, true) assert.NotEqual(generated1, generated1a) @@ -255,7 +255,7 @@ func (s *recordingTests) TestGenerateAlphaNumericID() { generated2, err := target2.GenerateAlphaNumericID(prefix, 10, true) // The two generated Ids should be the same since target2 loaded the saved random seed from target - assert.Equal(*generated2, *generated1) + assert.Equal(generated2, generated1) err = target.Stop() assert.Nil(err) @@ -273,7 +273,7 @@ func (s *recordingTests) TestRecordRequestsAndDoMatching() { target.recorder.SetTransport(rt) path, err := target.GenerateAlphaNumericID("", 5, true) - reqUrl := server.URL() + "/" + *path + reqUrl := server.URL() + "/" + path req, _ := http.NewRequest(http.MethodPost, reqUrl, nil) @@ -295,7 +295,7 @@ func (s *recordingTests) TestRecordRequestsAndDoMatching() { // re-create the random url using the recorded variables path, err = target.GenerateAlphaNumericID("", 5, true) - reqUrl = server.URL() + "/" + *path + reqUrl = server.URL() + "/" + path req, _ = http.NewRequest(http.MethodPost, reqUrl, nil) // playback the request @@ -316,7 +316,7 @@ func (s *recordingTests) TestRecordRequestsAndFailMatchingForMissingRecording() target.recorder.SetTransport(rt) path, err := target.GenerateAlphaNumericID("", 5, true) - reqUrl := server.URL() + "/" + *path + reqUrl := server.URL() + "/" + path req, _ := http.NewRequest(http.MethodPost, reqUrl, nil) diff --git a/sdk/tables/aztables/tableClient_test.go b/sdk/tables/aztables/tableClient_test.go index 5a3a666b123b..f3a3ce86dada 100644 --- a/sdk/tables/aztables/tableClient_test.go +++ b/sdk/tables/aztables/tableClient_test.go @@ -135,7 +135,7 @@ func (s *tableClientLiveTests) init(doCreate bool) (*TableClient, func()) { assert := assert.New(s.T()) context := getTestContext(s.T().Name()) tableName, _ := getTableName(context) - client := context.client.GetTableClient(*tableName) + client := context.client.GetTableClient(tableName) if doCreate { _, err := client.Create(ctx) if err != nil { diff --git a/sdk/tables/aztables/tableServiceClient_test.go b/sdk/tables/aztables/tableServiceClient_test.go index 1e62c0ad6183..f57f23d60afd 100644 --- a/sdk/tables/aztables/tableServiceClient_test.go +++ b/sdk/tables/aztables/tableServiceClient_test.go @@ -36,12 +36,12 @@ func (s *tableServiceClientLiveTests) TestServiceErrors() { context := getTestContext(s.T().Name()) tableName, err := getTableName(context) - _, err = context.client.Create(ctx, *tableName) - defer context.client.Delete(ctx, *tableName) + _, err = context.client.Create(ctx, tableName) + defer context.client.Delete(ctx, tableName) assert.Nil(err) // Create a duplicate table to produce an error - _, svcErr := context.client.Create(ctx, *tableName) + _, svcErr := context.client.Create(ctx, tableName) assert.Equal(svcErr.RawResponse().StatusCode, http.StatusConflict) } @@ -50,11 +50,11 @@ func (s *tableServiceClientLiveTests) TestCreateTable() { context := getTestContext(s.T().Name()) tableName, err := getTableName(context) - resp, err := context.client.Create(ctx, *tableName) - defer context.client.Delete(ctx, *tableName) + resp, err := context.client.Create(ctx, tableName) + defer context.client.Delete(ctx, tableName) assert.Nil(err) - assert.Equal(*resp.TableResponse.TableName, *tableName) + assert.Equal(*resp.TableResponse.TableName, tableName) } func (s *tableServiceClientLiveTests) TestQueryTable() { @@ -70,10 +70,10 @@ func (s *tableServiceClientLiveTests) TestQueryTable() { for i := 0; i < tableCount; i++ { if i < (tableCount - 1) { name, _ := getTableName(context, prefix1) - tableNames[i] = *name + tableNames[i] = name } else { name, _ := getTableName(context, prefix2) - tableNames[i] = *name + tableNames[i] = name } _, err := context.client.Create(ctx, tableNames[i]) assert.Nil(err) diff --git a/sdk/tables/aztables/zt_tableRecordedTests.go b/sdk/tables/aztables/zt_tableRecordedTests.go index 62e0f9ffd74e..7c42ec9545ab 100644 --- a/sdk/tables/aztables/zt_tableRecordedTests.go +++ b/sdk/tables/aztables/zt_tableRecordedTests.go @@ -114,7 +114,7 @@ func getTestContext(key string) *testContext { return clientsMap[key] } -func getTableName(context *testContext, prefix ...string) (*string, error) { +func getTableName(context *testContext, prefix ...string) (string, error) { if len(prefix) == 0 { return context.recording.GenerateAlphaNumericID(tableNamePrefix, 20, true) } else { From 7a62feaf90cdade054157dd8f8167f59db539028 Mon Sep 17 00:00:00 2001 From: Christopher Scott Date: Wed, 21 Apr 2021 09:17:40 -0500 Subject: [PATCH 16/18] clean to just testFramework --- sdk/tables/aztables/CHANGELOG.md | 2 +- sdk/tables/aztables/ci.yml | 4 +- sdk/tables/aztables/go.mod | 8 +- sdk/tables/aztables/go.sum | 24 +- .../TestCreateTable-variables.yaml | 5 - .../TestCreateTable.yaml | 75 --- .../TestQueryTable-variables.yaml | 5 - .../TestQueryTable.yaml | 499 ---------------- .../TestServiceErrors-variables.yaml | 5 - .../TestServiceErrors.yaml | 113 ---- .../TestCreateTable-variables.yaml | 5 - .../TestCreateTable.yaml | 85 --- .../TestQueryTable-variables.yaml | 5 - .../TestQueryTable.yaml | 532 ------------------ .../TestServiceErrors-variables.yaml | 5 - .../TestServiceErrors.yaml | 129 ----- .../TestAddComplexEntity-variables.yaml | 6 - .../TestAddComplexEntity.yaml | 121 ---- .../TestAddEntity-variables.yaml | 5 - .../TestTableClient_Cosmos/TestAddEntity.yaml | 121 ---- .../TestCreateTable-variables.yaml | 5 - .../TestCreateTable.yaml | 75 --- .../TestQuerySimpleEntity-variables.yaml | 5 - .../TestQuerySimpleEntity.yaml | 342 ----------- .../TestServiceErrors-variables.yaml | 5 - .../TestServiceErrors.yaml | 113 ---- .../TestAddComplexEntity-variables.yaml | 6 - .../TestAddComplexEntity.yaml | 139 ----- .../TestAddEntity-variables.yaml | 5 - .../TestAddEntity.yaml | 139 ----- .../TestCreateTable-variables.yaml | 5 - .../TestCreateTable.yaml | 85 --- .../TestQuerySimpleEntity-variables.yaml | 5 - .../TestQuerySimpleEntity.yaml | 398 ------------- .../TestServiceErrors-variables.yaml | 5 - .../TestServiceErrors.yaml | 129 ----- sdk/tables/aztables/tableClient.go | 65 +-- sdk/tables/aztables/tableClient_test.go | 160 +----- sdk/tables/aztables/tableServiceClient.go | 62 -- .../aztables/tableServiceClient_test.go | 120 ---- sdk/tables/aztables/zc_client_options.go | 6 +- sdk/tables/aztables/zc_tableConstants.go | 23 - sdk/tables/aztables/zc_table_pagers.go | 442 --------------- sdk/tables/aztables/zc_table_pagers_test.go | 244 -------- sdk/tables/aztables/zt_tableRecordedTests.go | 179 ------ sdk/tables/aztables/zt_test.go | 123 ++++ .../aztables/zz_generated_connection.go | 4 +- 47 files changed, 155 insertions(+), 4488 deletions(-) delete mode 100644 sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestCreateTable-variables.yaml delete mode 100644 sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestCreateTable.yaml delete mode 100644 sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestQueryTable-variables.yaml delete mode 100644 sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestQueryTable.yaml delete mode 100644 sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestServiceErrors-variables.yaml delete mode 100644 sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestServiceErrors.yaml delete mode 100644 sdk/tables/aztables/recordings/TestServiceClient_Storage/TestCreateTable-variables.yaml delete mode 100644 sdk/tables/aztables/recordings/TestServiceClient_Storage/TestCreateTable.yaml delete mode 100644 sdk/tables/aztables/recordings/TestServiceClient_Storage/TestQueryTable-variables.yaml delete mode 100644 sdk/tables/aztables/recordings/TestServiceClient_Storage/TestQueryTable.yaml delete mode 100644 sdk/tables/aztables/recordings/TestServiceClient_Storage/TestServiceErrors-variables.yaml delete mode 100644 sdk/tables/aztables/recordings/TestServiceClient_Storage/TestServiceErrors.yaml delete mode 100644 sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestAddComplexEntity-variables.yaml delete mode 100644 sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestAddComplexEntity.yaml delete mode 100644 sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestAddEntity-variables.yaml delete mode 100644 sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestAddEntity.yaml delete mode 100644 sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestCreateTable-variables.yaml delete mode 100644 sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestCreateTable.yaml delete mode 100644 sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestQuerySimpleEntity-variables.yaml delete mode 100644 sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestQuerySimpleEntity.yaml delete mode 100644 sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestServiceErrors-variables.yaml delete mode 100644 sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestServiceErrors.yaml delete mode 100644 sdk/tables/aztables/recordings/TestTableClient_Storage/TestAddComplexEntity-variables.yaml delete mode 100644 sdk/tables/aztables/recordings/TestTableClient_Storage/TestAddComplexEntity.yaml delete mode 100644 sdk/tables/aztables/recordings/TestTableClient_Storage/TestAddEntity-variables.yaml delete mode 100644 sdk/tables/aztables/recordings/TestTableClient_Storage/TestAddEntity.yaml delete mode 100644 sdk/tables/aztables/recordings/TestTableClient_Storage/TestCreateTable-variables.yaml delete mode 100644 sdk/tables/aztables/recordings/TestTableClient_Storage/TestCreateTable.yaml delete mode 100644 sdk/tables/aztables/recordings/TestTableClient_Storage/TestQuerySimpleEntity-variables.yaml delete mode 100644 sdk/tables/aztables/recordings/TestTableClient_Storage/TestQuerySimpleEntity.yaml delete mode 100644 sdk/tables/aztables/recordings/TestTableClient_Storage/TestServiceErrors-variables.yaml delete mode 100644 sdk/tables/aztables/recordings/TestTableClient_Storage/TestServiceErrors.yaml delete mode 100644 sdk/tables/aztables/tableServiceClient.go delete mode 100644 sdk/tables/aztables/tableServiceClient_test.go delete mode 100644 sdk/tables/aztables/zc_tableConstants.go delete mode 100644 sdk/tables/aztables/zc_table_pagers.go delete mode 100644 sdk/tables/aztables/zc_table_pagers_test.go delete mode 100644 sdk/tables/aztables/zt_tableRecordedTests.go create mode 100644 sdk/tables/aztables/zt_test.go diff --git a/sdk/tables/aztables/CHANGELOG.md b/sdk/tables/aztables/CHANGELOG.md index 79cb7d0abef2..b8c2e452d173 100644 --- a/sdk/tables/aztables/CHANGELOG.md +++ b/sdk/tables/aztables/CHANGELOG.md @@ -1,3 +1,3 @@ # Release History -## 0.1.0 (Unreleased) \ No newline at end of file +## v0.1.0 (Unreleased) diff --git a/sdk/tables/aztables/ci.yml b/sdk/tables/aztables/ci.yml index 900004ccf8bc..176bc16e42c8 100644 --- a/sdk/tables/aztables/ci.yml +++ b/sdk/tables/aztables/ci.yml @@ -10,6 +10,6 @@ pr: - sdk/tables/aztables/ stages: -- template: ../../eng/pipelines/templates/jobs/archetype-sdk-client.yml +- template: ../../../eng/pipelines/templates/jobs/archetype-sdk-client.yml parameters: - ServiceDirectory: 'tables' \ No newline at end of file + ServiceDirectory: 'tables' diff --git a/sdk/tables/aztables/go.mod b/sdk/tables/aztables/go.mod index d19e9f2dac53..a37066df4bb0 100644 --- a/sdk/tables/aztables/go.mod +++ b/sdk/tables/aztables/go.mod @@ -2,11 +2,7 @@ module github.com/Azure/azure-sdk-for-go/sdk/tables/aztables go 1.13 -replace github.com/Azure/azure-sdk-for-go/sdk/internal => ../../internal - require ( - github.com/Azure/azure-sdk-for-go/sdk/azcore v0.14.2 - github.com/Azure/azure-sdk-for-go/sdk/internal v0.5.0 - github.com/google/uuid v1.2.0 // indirect - github.com/stretchr/testify v1.7.0 + github.com/Azure/azure-sdk-for-go/sdk/azcore v0.14.1 + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c ) diff --git a/sdk/tables/aztables/go.sum b/sdk/tables/aztables/go.sum index d5cfe51f882e..369497e547f8 100644 --- a/sdk/tables/aztables/go.sum +++ b/sdk/tables/aztables/go.sum @@ -1,22 +1,12 @@ -github.com/Azure/azure-sdk-for-go/sdk/azcore v0.14.2 h1:jBp1eg+iY1S6SEjISakVfHmvDxfj8bg1Mw9JFwpCKag= -github.com/Azure/azure-sdk-for-go/sdk/azcore v0.14.2/go.mod h1:pElNP+u99BvCZD+0jOlhI9OC/NB2IDTOTGZOZH0Qhq8= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dnaeon/go-vcr v1.1.0 h1:ReYa/UBrRyQdant9B4fNHGoCNKw6qh6P0fsdGmZpR7c= -github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= -github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= -github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/Azure/azure-sdk-for-go/sdk/azcore v0.14.1 h1:7JdDsau2B5IZc0d0CPvSMn8DxJ3GRBxtFS7OrZPIJdA= +github.com/Azure/azure-sdk-for-go/sdk/azcore v0.14.1/go.mod h1:pElNP+u99BvCZD+0jOlhI9OC/NB2IDTOTGZOZH0Qhq8= +github.com/Azure/azure-sdk-for-go/sdk/internal v0.5.0 h1:HG1ggl8L3ZkV/Ydanf7lKr5kkhhPGCpWdnr1J6v7cO4= +github.com/Azure/azure-sdk-for-go/sdk/internal v0.5.0/go.mod h1:k4KbFSunV/+0hOHL1vyFaPsiYQ1Vmvy1TBpmtvCDLZM= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -29,11 +19,5 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestCreateTable-variables.yaml b/sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestCreateTable-variables.yaml deleted file mode 100644 index 7c9e2af36ee8..000000000000 --- a/sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestCreateTable-variables.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -COSMOS_TABLES_ENDPOINT_SUFFIX: cosmos.azure.com -TABLES_COSMOS_ACCOUNT_NAME: chrisstablesprim -TABLES_PRIMARY_COSMOS_ACCOUNT_KEY: Kg== -randomSeed: "1617573293" diff --git a/sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestCreateTable.yaml b/sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestCreateTable.yaml deleted file mode 100644 index 032f93240511..000000000000 --- a/sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestCreateTable.yaml +++ /dev/null @@ -1,75 +0,0 @@ ---- -version: 1 -interactions: -- request: - body: '{"TableName":"gotablecwmvbx3xi23m7"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "36" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:53 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/Tables - method: POST - response: - body: '{"TableName":"gotablecwmvbx3xi23m7","odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables/@Element"}' - headers: - Content-Type: - - application/json;odata=minimalmetadata - Date: - - Sun, 04 Apr 2021 21:54:53 GMT - Etag: - - W/"datetime'2021-04-04T21%3A54%3A53.3743624Z'" - Location: - - https://chrisstablesprim.table.cosmos.azure.com/Tables('gotablecwmvbx3xi23m7') - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - 33edc858-c2fc-436f-a0a0-8f909cfd1114 - status: 201 Created - code: 201 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json - Authorization: - - sanitized - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:53 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/Tables('gotablecwmvbx3xi23m7') - method: DELETE - response: - body: "" - headers: - Content-Length: - - "0" - Date: - - Sun, 04 Apr 2021 21:54:53 GMT - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - 654da1b1-025b-451e-8d64-d3c4afe7739a - status: 204 No Content - code: 204 - duration: "" diff --git a/sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestQueryTable-variables.yaml b/sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestQueryTable-variables.yaml deleted file mode 100644 index e1d3c746ac8b..000000000000 --- a/sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestQueryTable-variables.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -COSMOS_TABLES_ENDPOINT_SUFFIX: cosmos.azure.com -TABLES_COSMOS_ACCOUNT_NAME: chrisstablesprim -TABLES_PRIMARY_COSMOS_ACCOUNT_KEY: Kg== -randomSeed: "1617573294" diff --git a/sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestQueryTable.yaml b/sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestQueryTable.yaml deleted file mode 100644 index 4451edbf754c..000000000000 --- a/sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestQueryTable.yaml +++ /dev/null @@ -1,499 +0,0 @@ ---- -version: 1 -interactions: -- request: - body: '{"TableName":"zzza6868drab2e097oxu"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "36" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:54 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/Tables - method: POST - response: - body: '{"TableName":"zzza6868drab2e097oxu","odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables/@Element"}' - headers: - Content-Type: - - application/json;odata=minimalmetadata - Date: - - Sun, 04 Apr 2021 21:54:53 GMT - Etag: - - W/"datetime'2021-04-04T21%3A54%3A54.2225416Z'" - Location: - - https://chrisstablesprim.table.cosmos.azure.com/Tables('zzza6868drab2e097oxu') - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - b9dd1425-f416-44cd-9759-fa6ddc763d8e - status: 201 Created - code: 201 - duration: "" -- request: - body: '{"TableName":"zzza47kqkxef1dqg6hk5"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "36" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:54 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/Tables - method: POST - response: - body: '{"TableName":"zzza47kqkxef1dqg6hk5","odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables/@Element"}' - headers: - Content-Type: - - application/json;odata=minimalmetadata - Date: - - Sun, 04 Apr 2021 21:54:55 GMT - Etag: - - W/"datetime'2021-04-04T21%3A54%3A54.7395592Z'" - Location: - - https://chrisstablesprim.table.cosmos.azure.com/Tables('zzza47kqkxef1dqg6hk5') - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - 7cc0bdc4-bc2e-41a5-a9d5-718481425834 - status: 201 Created - code: 201 - duration: "" -- request: - body: '{"TableName":"zzzancjsimv46ssmus2y"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "36" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:55 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/Tables - method: POST - response: - body: '{"TableName":"zzzancjsimv46ssmus2y","odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables/@Element"}' - headers: - Content-Type: - - application/json;odata=minimalmetadata - Date: - - Sun, 04 Apr 2021 21:54:55 GMT - Etag: - - W/"datetime'2021-04-04T21%3A54%3A55.2994824Z'" - Location: - - https://chrisstablesprim.table.cosmos.azure.com/Tables('zzzancjsimv46ssmus2y') - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - 458c58e3-3247-448a-a542-de9f20e68872 - status: 201 Created - code: 201 - duration: "" -- request: - body: '{"TableName":"zzzau7wd11jeadrhkzia"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "36" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:55 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/Tables - method: POST - response: - body: '{"TableName":"zzzau7wd11jeadrhkzia","odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables/@Element"}' - headers: - Content-Type: - - application/json;odata=minimalmetadata - Date: - - Sun, 04 Apr 2021 21:54:56 GMT - Etag: - - W/"datetime'2021-04-04T21%3A54%3A55.8298120Z'" - Location: - - https://chrisstablesprim.table.cosmos.azure.com/Tables('zzzau7wd11jeadrhkzia') - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - e08277e1-0ac2-4cb7-a9c2-3ad4d593d33e - status: 201 Created - code: 201 - duration: "" -- request: - body: '{"TableName":"zzzbm74eob1xykl1zb71"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "36" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:56 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/Tables - method: POST - response: - body: '{"TableName":"zzzbm74eob1xykl1zb71","odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables/@Element"}' - headers: - Content-Type: - - application/json;odata=minimalmetadata - Date: - - Sun, 04 Apr 2021 21:54:56 GMT - Etag: - - W/"datetime'2021-04-04T21%3A54%3A56.4097032Z'" - Location: - - https://chrisstablesprim.table.cosmos.azure.com/Tables('zzzbm74eob1xykl1zb71') - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - aba90f45-d352-46e5-8d0b-32d749a29ac3 - status: 201 Created - code: 201 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:56 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/Tables?%24filter=TableName+ge+%27zzza%27+and+TableName+lt+%27zzzb%27 - method: GET - response: - body: '{"value":[{"TableName":"zzza6868drab2e097oxu"},{"TableName":"zzza47kqkxef1dqg6hk5"},{"TableName":"zzzancjsimv46ssmus2y"},{"TableName":"zzzau7wd11jeadrhkzia"}],"odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables"}' - headers: - Content-Type: - - application/json;odata=minimalmetadata - Date: - - Sun, 04 Apr 2021 21:54:56 GMT - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - e277f56f-be38-4847-bcc7-d404818cc2a4 - status: 200 OK - code: 200 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:57 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/Tables?%24filter=TableName+ge+%27zzza%27+and+TableName+lt+%27zzzb%27&%24top=2 - method: GET - response: - body: '{"value":[{"TableName":"zzza6868drab2e097oxu"},{"TableName":"zzza47kqkxef1dqg6hk5"}],"odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables"}' - headers: - Content-Type: - - application/json;odata=minimalmetadata - Date: - - Sun, 04 Apr 2021 21:54:56 GMT - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Continuation-Nexttablename: - - -RID:~-mg9ANt+LD8=#RT:1#TRC:2 - X-Ms-Request-Id: - - 89b83810-e42f-46f9-a174-3a0cd1ebd42b - status: 200 OK - code: 200 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:57 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/Tables?%24filter=TableName+ge+%27zzza%27+and+TableName+lt+%27zzzb%27&%24top=2&NextTableName=-RID%3A~-mg9ANt%2BLD8%3D%23RT%3A1%23TRC%3A2 - method: GET - response: - body: '{"value":[{"TableName":"zzzancjsimv46ssmus2y"},{"TableName":"zzzau7wd11jeadrhkzia"}],"odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables"}' - headers: - Content-Type: - - application/json;odata=minimalmetadata - Date: - - Sun, 04 Apr 2021 21:54:56 GMT - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Continuation-Nexttablename: - - -RID:~-mg9AOab5rE=#RT:2#TRC:4 - X-Ms-Request-Id: - - 5b359f2a-f01b-4b51-88b8-f555384be342 - status: 200 OK - code: 200 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:57 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/Tables?%24filter=TableName+ge+%27zzza%27+and+TableName+lt+%27zzzb%27&%24top=2&NextTableName=-RID%3A~-mg9AOab5rE%3D%23RT%3A2%23TRC%3A4 - method: GET - response: - body: '{"value":[],"odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables"}' - headers: - Content-Type: - - application/json;odata=minimalmetadata - Date: - - Sun, 04 Apr 2021 21:54:56 GMT - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - bac31683-48dc-4dba-86b7-5299f8f80b14 - status: 200 OK - code: 200 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json - Authorization: - - sanitized - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:57 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/Tables('zzza6868drab2e097oxu') - method: DELETE - response: - body: "" - headers: - Content-Length: - - "0" - Date: - - Sun, 04 Apr 2021 21:54:57 GMT - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - 4e2b7f94-e9a9-4397-9ec1-c4808f908cf0 - status: 204 No Content - code: 204 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json - Authorization: - - sanitized - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:57 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/Tables('zzza47kqkxef1dqg6hk5') - method: DELETE - response: - body: "" - headers: - Content-Length: - - "0" - Date: - - Sun, 04 Apr 2021 21:54:57 GMT - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - 0c5dda5b-2983-493f-8114-90378a12a073 - status: 204 No Content - code: 204 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json - Authorization: - - sanitized - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:58 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/Tables('zzzancjsimv46ssmus2y') - method: DELETE - response: - body: "" - headers: - Content-Length: - - "0" - Date: - - Sun, 04 Apr 2021 21:54:57 GMT - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - 7f4c8bcf-9801-493b-90b8-84ee3935af02 - status: 204 No Content - code: 204 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json - Authorization: - - sanitized - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:58 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/Tables('zzzau7wd11jeadrhkzia') - method: DELETE - response: - body: "" - headers: - Content-Length: - - "0" - Date: - - Sun, 04 Apr 2021 21:54:58 GMT - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - a05000dd-1cfe-4256-88b7-e6be74a2d7df - status: 204 No Content - code: 204 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json - Authorization: - - sanitized - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:58 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/Tables('zzzbm74eob1xykl1zb71') - method: DELETE - response: - body: "" - headers: - Content-Length: - - "0" - Date: - - Sun, 04 Apr 2021 21:54:58 GMT - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - 81acb8ac-7460-4aa8-b548-e426c88aba21 - status: 204 No Content - code: 204 - duration: "" diff --git a/sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestServiceErrors-variables.yaml b/sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestServiceErrors-variables.yaml deleted file mode 100644 index 760bc4d4fdfb..000000000000 --- a/sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestServiceErrors-variables.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -COSMOS_TABLES_ENDPOINT_SUFFIX: cosmos.azure.com -TABLES_COSMOS_ACCOUNT_NAME: chrisstablesprim -TABLES_PRIMARY_COSMOS_ACCOUNT_KEY: Kg== -randomSeed: "1617573550" diff --git a/sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestServiceErrors.yaml b/sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestServiceErrors.yaml deleted file mode 100644 index d3b9bf432eb8..000000000000 --- a/sdk/tables/aztables/recordings/TestServiceClient_Cosmos/TestServiceErrors.yaml +++ /dev/null @@ -1,113 +0,0 @@ ---- -version: 1 -interactions: -- request: - body: '{"TableName":"gotable5hickrxl8lpbo"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "36" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:59:10 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/Tables - method: POST - response: - body: '{"TableName":"gotable5hickrxl8lpbo","odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables/@Element"}' - headers: - Content-Type: - - application/json;odata=minimalmetadata - Date: - - Sun, 04 Apr 2021 21:59:11 GMT - Etag: - - W/"datetime'2021-04-04T21%3A59%3A10.9652488Z'" - Location: - - https://chrisstablesprim.table.cosmos.azure.com/Tables('gotable5hickrxl8lpbo') - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - a5903255-58e5-4c43-bad9-f5e92cd5bd68 - status: 201 Created - code: 201 - duration: "" -- request: - body: '{"TableName":"gotable5hickrxl8lpbo"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "36" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:59:11 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/Tables - method: POST - response: - body: "{\"odata.error\":{\"code\":\"TableAlreadyExists\",\"message\":{\"lang\":\"en-us\",\"value\":\"The - specified table already exists.\\nRequestID:e216471c-9dae-4105-99a9-66a274775cce\\n\"}}}\r\n" - headers: - Content-Type: - - application/json;odata=minimalmetadata - Date: - - Sun, 04 Apr 2021 21:59:11 GMT - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - e216471c-9dae-4105-99a9-66a274775cce - status: 409 Conflict - code: 409 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json - Authorization: - - sanitized - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:59:11 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/Tables('gotable5hickrxl8lpbo') - method: DELETE - response: - body: "" - headers: - Content-Length: - - "0" - Date: - - Sun, 04 Apr 2021 21:59:11 GMT - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - c8bbfa46-7d78-46af-a6cb-b54bd57237af - status: 204 No Content - code: 204 - duration: "" diff --git a/sdk/tables/aztables/recordings/TestServiceClient_Storage/TestCreateTable-variables.yaml b/sdk/tables/aztables/recordings/TestServiceClient_Storage/TestCreateTable-variables.yaml deleted file mode 100644 index 9b7c965397f6..000000000000 --- a/sdk/tables/aztables/recordings/TestServiceClient_Storage/TestCreateTable-variables.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -STORAGE_ENDPOINT_SUFFIX: core.windows.net -TABLES_PRIMARY_STORAGE_ACCOUNT_KEY: Kg== -TABLES_STORAGE_ACCOUNT_NAME: chrisstablesprim -randomSeed: "1617573291" diff --git a/sdk/tables/aztables/recordings/TestServiceClient_Storage/TestCreateTable.yaml b/sdk/tables/aztables/recordings/TestServiceClient_Storage/TestCreateTable.yaml deleted file mode 100644 index f5f90205815d..000000000000 --- a/sdk/tables/aztables/recordings/TestServiceClient_Storage/TestCreateTable.yaml +++ /dev/null @@ -1,85 +0,0 @@ ---- -version: 1 -interactions: -- request: - body: '{"TableName":"gotablep06y44pq0dcqy"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "36" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:51 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/Tables - method: POST - response: - body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#Tables/@Element","TableName":"gotablep06y44pq0dcqy"}' - headers: - Cache-Control: - - no-cache - Content-Type: - - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 - Date: - - Sun, 04 Apr 2021 21:54:51 GMT - Location: - - https://chrisstablesprim.table.core.windows.net/Tables('gotablep06y44pq0dcqy') - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - aa171c82-c002-0053-409d-291720000000 - X-Ms-Version: - - "2019-02-02" - status: 201 Created - code: 201 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json - Authorization: - - sanitized - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:51 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/Tables('gotablep06y44pq0dcqy') - method: DELETE - response: - body: "" - headers: - Cache-Control: - - no-cache - Content-Length: - - "0" - Date: - - Sun, 04 Apr 2021 21:54:51 GMT - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - aa171c8d-c002-0053-4a9d-291720000000 - X-Ms-Version: - - "2019-02-02" - status: 204 No Content - code: 204 - duration: "" diff --git a/sdk/tables/aztables/recordings/TestServiceClient_Storage/TestQueryTable-variables.yaml b/sdk/tables/aztables/recordings/TestServiceClient_Storage/TestQueryTable-variables.yaml deleted file mode 100644 index 9b7c965397f6..000000000000 --- a/sdk/tables/aztables/recordings/TestServiceClient_Storage/TestQueryTable-variables.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -STORAGE_ENDPOINT_SUFFIX: core.windows.net -TABLES_PRIMARY_STORAGE_ACCOUNT_KEY: Kg== -TABLES_STORAGE_ACCOUNT_NAME: chrisstablesprim -randomSeed: "1617573291" diff --git a/sdk/tables/aztables/recordings/TestServiceClient_Storage/TestQueryTable.yaml b/sdk/tables/aztables/recordings/TestServiceClient_Storage/TestQueryTable.yaml deleted file mode 100644 index 2431a475cb56..000000000000 --- a/sdk/tables/aztables/recordings/TestServiceClient_Storage/TestQueryTable.yaml +++ /dev/null @@ -1,532 +0,0 @@ ---- -version: 1 -interactions: -- request: - body: '{"TableName":"zzzap06y44pq0dcqyefd"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "36" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:51 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/Tables - method: POST - response: - body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#Tables/@Element","TableName":"zzzap06y44pq0dcqyefd"}' - headers: - Cache-Control: - - no-cache - Content-Type: - - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 - Date: - - Sun, 04 Apr 2021 21:54:51 GMT - Location: - - https://chrisstablesprim.table.core.windows.net/Tables('zzzap06y44pq0dcqyefd') - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - aa171c98-c002-0053-539d-291720000000 - X-Ms-Version: - - "2019-02-02" - status: 201 Created - code: 201 - duration: "" -- request: - body: '{"TableName":"zzzas5q9cqk9i1o44v25"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "36" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:52 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/Tables - method: POST - response: - body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#Tables/@Element","TableName":"zzzas5q9cqk9i1o44v25"}' - headers: - Cache-Control: - - no-cache - Content-Type: - - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 - Date: - - Sun, 04 Apr 2021 21:54:51 GMT - Location: - - https://chrisstablesprim.table.core.windows.net/Tables('zzzas5q9cqk9i1o44v25') - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - aa171ca1-c002-0053-5b9d-291720000000 - X-Ms-Version: - - "2019-02-02" - status: 201 Created - code: 201 - duration: "" -- request: - body: '{"TableName":"zzzavphdrg4ipo7z4boc"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "36" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:52 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/Tables - method: POST - response: - body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#Tables/@Element","TableName":"zzzavphdrg4ipo7z4boc"}' - headers: - Cache-Control: - - no-cache - Content-Type: - - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 - Date: - - Sun, 04 Apr 2021 21:54:51 GMT - Location: - - https://chrisstablesprim.table.core.windows.net/Tables('zzzavphdrg4ipo7z4boc') - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - aa171ca9-c002-0053-629d-291720000000 - X-Ms-Version: - - "2019-02-02" - status: 201 Created - code: 201 - duration: "" -- request: - body: '{"TableName":"zzzanoa2c4lxhmr55w1n"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "36" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:52 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/Tables - method: POST - response: - body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#Tables/@Element","TableName":"zzzanoa2c4lxhmr55w1n"}' - headers: - Cache-Control: - - no-cache - Content-Type: - - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 - Date: - - Sun, 04 Apr 2021 21:54:51 GMT - Location: - - https://chrisstablesprim.table.core.windows.net/Tables('zzzanoa2c4lxhmr55w1n') - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - aa171cb5-c002-0053-6c9d-291720000000 - X-Ms-Version: - - "2019-02-02" - status: 201 Created - code: 201 - duration: "" -- request: - body: '{"TableName":"zzzbq0ics0v4b1nbyytz"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "36" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:52 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/Tables - method: POST - response: - body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#Tables/@Element","TableName":"zzzbq0ics0v4b1nbyytz"}' - headers: - Cache-Control: - - no-cache - Content-Type: - - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 - Date: - - Sun, 04 Apr 2021 21:54:51 GMT - Location: - - https://chrisstablesprim.table.core.windows.net/Tables('zzzbq0ics0v4b1nbyytz') - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - aa171cbe-c002-0053-739d-291720000000 - X-Ms-Version: - - "2019-02-02" - status: 201 Created - code: 201 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:52 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/Tables?%24filter=TableName+ge+%27zzza%27+and+TableName+lt+%27zzzb%27 - method: GET - response: - body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#Tables","value":[{"TableName":"zzzanoa2c4lxhmr55w1n"},{"TableName":"zzzap06y44pq0dcqyefd"},{"TableName":"zzzas5q9cqk9i1o44v25"},{"TableName":"zzzavphdrg4ipo7z4boc"}]}' - headers: - Cache-Control: - - no-cache - Content-Type: - - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 - Date: - - Sun, 04 Apr 2021 21:54:51 GMT - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - aa171ccc-c002-0053-7f9d-291720000000 - X-Ms-Version: - - "2019-02-02" - status: 200 OK - code: 200 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:52 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/Tables?%24filter=TableName+ge+%27zzza%27+and+TableName+lt+%27zzzb%27&%24top=2 - method: GET - response: - body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#Tables","value":[{"TableName":"zzzanoa2c4lxhmr55w1n"},{"TableName":"zzzap06y44pq0dcqyefd"}]}' - headers: - Cache-Control: - - no-cache - Content-Type: - - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 - Date: - - Sun, 04 Apr 2021 21:54:51 GMT - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Continuation-Nexttablename: - - 1!52!enp6YXM1cTljcWs5aTFvNDR2MjUBMDFkNzI5OWQyM2U4NjU2Yw-- - X-Ms-Request-Id: - - aa171ce3-c002-0053-159d-291720000000 - X-Ms-Version: - - "2019-02-02" - status: 200 OK - code: 200 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:52 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/Tables?%24filter=TableName+ge+%27zzza%27+and+TableName+lt+%27zzzb%27&%24top=2&NextTableName=1%2152%21enp6YXM1cTljcWs5aTFvNDR2MjUBMDFkNzI5OWQyM2U4NjU2Yw-- - method: GET - response: - body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#Tables","value":[{"TableName":"zzzas5q9cqk9i1o44v25"},{"TableName":"zzzavphdrg4ipo7z4boc"}]}' - headers: - Cache-Control: - - no-cache - Content-Type: - - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 - Date: - - Sun, 04 Apr 2021 21:54:51 GMT - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - aa171cf4-c002-0053-269d-291720000000 - X-Ms-Version: - - "2019-02-02" - status: 200 OK - code: 200 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json - Authorization: - - sanitized - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:52 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/Tables('zzzap06y44pq0dcqyefd') - method: DELETE - response: - body: "" - headers: - Cache-Control: - - no-cache - Content-Length: - - "0" - Date: - - Sun, 04 Apr 2021 21:54:52 GMT - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - aa171d07-c002-0053-369d-291720000000 - X-Ms-Version: - - "2019-02-02" - status: 204 No Content - code: 204 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json - Authorization: - - sanitized - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:52 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/Tables('zzzas5q9cqk9i1o44v25') - method: DELETE - response: - body: "" - headers: - Cache-Control: - - no-cache - Content-Length: - - "0" - Date: - - Sun, 04 Apr 2021 21:54:52 GMT - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - aa171d16-c002-0053-459d-291720000000 - X-Ms-Version: - - "2019-02-02" - status: 204 No Content - code: 204 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json - Authorization: - - sanitized - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:52 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/Tables('zzzavphdrg4ipo7z4boc') - method: DELETE - response: - body: "" - headers: - Cache-Control: - - no-cache - Content-Length: - - "0" - Date: - - Sun, 04 Apr 2021 21:54:52 GMT - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - aa171d2a-c002-0053-599d-291720000000 - X-Ms-Version: - - "2019-02-02" - status: 204 No Content - code: 204 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json - Authorization: - - sanitized - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:52 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/Tables('zzzanoa2c4lxhmr55w1n') - method: DELETE - response: - body: "" - headers: - Cache-Control: - - no-cache - Content-Length: - - "0" - Date: - - Sun, 04 Apr 2021 21:54:52 GMT - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - aa171d3d-c002-0053-6c9d-291720000000 - X-Ms-Version: - - "2019-02-02" - status: 204 No Content - code: 204 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json - Authorization: - - sanitized - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:53 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/Tables('zzzbq0ics0v4b1nbyytz') - method: DELETE - response: - body: "" - headers: - Cache-Control: - - no-cache - Content-Length: - - "0" - Date: - - Sun, 04 Apr 2021 21:54:52 GMT - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - aa171d51-c002-0053-7d9d-291720000000 - X-Ms-Version: - - "2019-02-02" - status: 204 No Content - code: 204 - duration: "" diff --git a/sdk/tables/aztables/recordings/TestServiceClient_Storage/TestServiceErrors-variables.yaml b/sdk/tables/aztables/recordings/TestServiceClient_Storage/TestServiceErrors-variables.yaml deleted file mode 100644 index 3f5acca6cabc..000000000000 --- a/sdk/tables/aztables/recordings/TestServiceClient_Storage/TestServiceErrors-variables.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -STORAGE_ENDPOINT_SUFFIX: core.windows.net -TABLES_PRIMARY_STORAGE_ACCOUNT_KEY: Kg== -TABLES_STORAGE_ACCOUNT_NAME: chrisstablesprim -randomSeed: "1617573550" diff --git a/sdk/tables/aztables/recordings/TestServiceClient_Storage/TestServiceErrors.yaml b/sdk/tables/aztables/recordings/TestServiceClient_Storage/TestServiceErrors.yaml deleted file mode 100644 index 55b918ae4d98..000000000000 --- a/sdk/tables/aztables/recordings/TestServiceClient_Storage/TestServiceErrors.yaml +++ /dev/null @@ -1,129 +0,0 @@ ---- -version: 1 -interactions: -- request: - body: '{"TableName":"gotable5hickrxl8lpbo"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "36" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:59:10 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/Tables - method: POST - response: - body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#Tables/@Element","TableName":"gotable5hickrxl8lpbo"}' - headers: - Cache-Control: - - no-cache - Content-Type: - - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 - Date: - - Sun, 04 Apr 2021 21:59:09 GMT - Location: - - https://chrisstablesprim.table.core.windows.net/Tables('gotable5hickrxl8lpbo') - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - a5bfa352-3002-0057-209d-299a27000000 - X-Ms-Version: - - "2019-02-02" - status: 201 Created - code: 201 - duration: "" -- request: - body: '{"TableName":"gotable5hickrxl8lpbo"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "36" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:59:10 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/Tables - method: POST - response: - body: '{"odata.error":{"code":"TableAlreadyExists","message":{"lang":"en-US","value":"The - table specified already exists.\nRequestId:a5bfa358-3002-0057-259d-299a27000000\nTime:2021-04-04T21:59:10.6883876Z"}}}' - headers: - Cache-Control: - - no-cache - Content-Type: - - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 - Date: - - Sun, 04 Apr 2021 21:59:10 GMT - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - a5bfa358-3002-0057-259d-299a27000000 - X-Ms-Version: - - "2019-02-02" - status: 409 Conflict - code: 409 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json - Authorization: - - sanitized - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:59:10 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/Tables('gotable5hickrxl8lpbo') - method: DELETE - response: - body: "" - headers: - Cache-Control: - - no-cache - Content-Length: - - "0" - Date: - - Sun, 04 Apr 2021 21:59:10 GMT - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - a5bfa35c-3002-0057-299d-299a27000000 - X-Ms-Version: - - "2019-02-02" - status: 204 No Content - code: 204 - duration: "" diff --git a/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestAddComplexEntity-variables.yaml b/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestAddComplexEntity-variables.yaml deleted file mode 100644 index a5295bc78865..000000000000 --- a/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestAddComplexEntity-variables.yaml +++ /dev/null @@ -1,6 +0,0 @@ ---- -COSMOS_TABLES_ENDPOINT_SUFFIX: cosmos.azure.com -TABLES_COSMOS_ACCOUNT_NAME: chrisstablesprim -TABLES_PRIMARY_COSMOS_ACCOUNT_KEY: Kg== -now: "2021-04-10T19:18:39.9706889-05:00" -randomSeed: "1618100318" diff --git a/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestAddComplexEntity.yaml b/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestAddComplexEntity.yaml deleted file mode 100644 index a90bdd2b73da..000000000000 --- a/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestAddComplexEntity.yaml +++ /dev/null @@ -1,121 +0,0 @@ ---- -version: 1 -interactions: -- request: - body: '{"TableName":"gotablexiw8zfw9mws0q"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "36" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 11 Apr 2021 00:18:38 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/Tables - method: POST - response: - body: '{"TableName":"gotablexiw8zfw9mws0q","odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables/@Element"}' - headers: - Content-Type: - - application/json;odata=minimalmetadata - Date: - - Sun, 11 Apr 2021 00:18:39 GMT - Etag: - - W/"datetime'2021-04-11T00%3A18%3A39.0866952Z'" - Location: - - https://chrisstablesprim.table.cosmos.azure.com/Tables('gotablexiw8zfw9mws0q') - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - 8d38468e-c994-404d-90cc-925db534f55f - status: 201 Created - code: 201 - duration: "" -- request: - body: '{"PartitionKey":"partition","RowKey":"row","SomeBinaryProperty":"c29tZSBieXRlcw==","SomeBinaryProperty@odata.type":"Edm.Binary","SomeDateProperty":"2021-04-11T00:18:39.9706889Z","SomeDateProperty@odata.type":"Edm.DateTime","SomeDoubleProperty0":1,"SomeDoubleProperty0@odata.type":"Edm.Double","SomeDoubleProperty1":1.2345,"SomeDoubleProperty1@odata.type":"Edm.Double","SomeGuidProperty":"4346b1a2-6141-483a-779b-1332da28b7d5","SomeGuidProperty@odata.type":"Edm.Guid","SomeInt64Property":"9223372036854775807","SomeInt64Property@odata.type":"Edm.Int64","SomeIntProperty":42,"SomePtrStringProperty":"some - pointer to string","SomeStringProperty":"some string"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "657" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - Prefer: - - return-no-content - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 11 Apr 2021 00:18:39 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/gotablexiw8zfw9mws0q - method: POST - response: - body: "" - headers: - Content-Length: - - "0" - Date: - - Sun, 11 Apr 2021 00:18:39 GMT - Etag: - - W/"datetime'2021-04-11T00%3A18%3A39.7189128Z'" - Location: - - https://chrisstablesprim.table.cosmos.azure.com/gotablexiw8zfw9mws0q(PartitionKey='partition',RowKey='row') - Preference-Applied: - - return-no-content - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - cec68903-00ae-4306-ae0a-5200c5f8bb60 - status: 204 No Content - code: 204 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json - Authorization: - - sanitized - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 11 Apr 2021 00:18:40 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/Tables('gotablexiw8zfw9mws0q') - method: DELETE - response: - body: "" - headers: - Content-Length: - - "0" - Date: - - Sun, 11 Apr 2021 00:18:39 GMT - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - ef2e97eb-017c-458b-be6d-9c130a33dfa6 - status: 204 No Content - code: 204 - duration: "" diff --git a/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestAddEntity-variables.yaml b/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestAddEntity-variables.yaml deleted file mode 100644 index dd3226b5e15b..000000000000 --- a/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestAddEntity-variables.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -COSMOS_TABLES_ENDPOINT_SUFFIX: cosmos.azure.com -TABLES_COSMOS_ACCOUNT_NAME: chrisstablesprim -TABLES_PRIMARY_COSMOS_ACCOUNT_KEY: Kg== -randomSeed: "1617580856" diff --git a/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestAddEntity.yaml b/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestAddEntity.yaml deleted file mode 100644 index f8993d0f4f77..000000000000 --- a/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestAddEntity.yaml +++ /dev/null @@ -1,121 +0,0 @@ ---- -version: 1 -interactions: -- request: - body: '{"TableName":"gotable7ws4xms1mzf9z"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "36" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Mon, 05 Apr 2021 00:00:56 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/Tables - method: POST - response: - body: '{"TableName":"gotable7ws4xms1mzf9z","odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables/@Element"}' - headers: - Content-Type: - - application/json;odata=minimalmetadata - Date: - - Mon, 05 Apr 2021 00:00:56 GMT - Etag: - - W/"datetime'2021-04-05T00%3A00%3A56.5521416Z'" - Location: - - https://chrisstablesprim.table.cosmos.azure.com/Tables('gotable7ws4xms1mzf9z') - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - 9ca87b9a-5e66-4ec1-97d0-0ea03fd04375 - status: 201 Created - code: 201 - duration: "" -- request: - body: '{"BoolProp":true,"IntProp":1,"PartitionKey":"partition","RowKey":"1","StringProp":"some - string 1"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "98" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - Prefer: - - return-no-content - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Mon, 05 Apr 2021 00:00:57 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/gotable7ws4xms1mzf9z - method: POST - response: - body: "" - headers: - Content-Length: - - "0" - Date: - - Mon, 05 Apr 2021 00:00:56 GMT - Etag: - - W/"datetime'2021-04-05T00%3A00%3A57.0277896Z'" - Location: - - https://chrisstablesprim.table.cosmos.azure.com/gotable7ws4xms1mzf9z(PartitionKey='partition',RowKey='1') - Preference-Applied: - - return-no-content - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - 57a01ccb-9f82-4e3c-a2be-601d4ed96b9d - status: 204 No Content - code: 204 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json - Authorization: - - sanitized - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Mon, 05 Apr 2021 00:00:57 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/Tables('gotable7ws4xms1mzf9z') - method: DELETE - response: - body: "" - headers: - Content-Length: - - "0" - Date: - - Mon, 05 Apr 2021 00:00:56 GMT - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - a515445a-2616-4e51-a4ea-bf4a788ad138 - status: 204 No Content - code: 204 - duration: "" diff --git a/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestCreateTable-variables.yaml b/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestCreateTable-variables.yaml deleted file mode 100644 index 5a403251353a..000000000000 --- a/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestCreateTable-variables.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -COSMOS_TABLES_ENDPOINT_SUFFIX: cosmos.azure.com -TABLES_COSMOS_ACCOUNT_NAME: chrisstablesprim -TABLES_PRIMARY_COSMOS_ACCOUNT_KEY: Kg== -randomSeed: "1617573289" diff --git a/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestCreateTable.yaml b/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestCreateTable.yaml deleted file mode 100644 index a60e34d514b1..000000000000 --- a/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestCreateTable.yaml +++ /dev/null @@ -1,75 +0,0 @@ ---- -version: 1 -interactions: -- request: - body: '{"TableName":"gotable3atc3ia9qkkbd"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "36" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:49 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/Tables - method: POST - response: - body: '{"TableName":"gotable3atc3ia9qkkbd","odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables/@Element"}' - headers: - Content-Type: - - application/json;odata=minimalmetadata - Date: - - Sun, 04 Apr 2021 21:54:50 GMT - Etag: - - W/"datetime'2021-04-04T21%3A54%3A49.7968136Z'" - Location: - - https://chrisstablesprim.table.cosmos.azure.com/Tables('gotable3atc3ia9qkkbd') - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - b9386c93-2228-4a78-bcab-652c24994580 - status: 201 Created - code: 201 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json - Authorization: - - sanitized - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:50 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/Tables('gotable3atc3ia9qkkbd') - method: DELETE - response: - body: "" - headers: - Content-Length: - - "0" - Date: - - Sun, 04 Apr 2021 21:54:50 GMT - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - f8cecc20-febd-48ed-950f-6fb532eb326d - status: 204 No Content - code: 204 - duration: "" diff --git a/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestQuerySimpleEntity-variables.yaml b/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestQuerySimpleEntity-variables.yaml deleted file mode 100644 index 05898e645159..000000000000 --- a/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestQuerySimpleEntity-variables.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -COSMOS_TABLES_ENDPOINT_SUFFIX: cosmos.azure.com -TABLES_COSMOS_ACCOUNT_NAME: chrisstablesprim -TABLES_PRIMARY_COSMOS_ACCOUNT_KEY: Kg== -randomSeed: "1617598959" diff --git a/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestQuerySimpleEntity.yaml b/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestQuerySimpleEntity.yaml deleted file mode 100644 index 4cc2c9ff4295..000000000000 --- a/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestQuerySimpleEntity.yaml +++ /dev/null @@ -1,342 +0,0 @@ ---- -version: 1 -interactions: -- request: - body: '{"TableName":"gotabledtlot4b2qfkop"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "36" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Mon, 05 Apr 2021 05:02:39 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/Tables - method: POST - response: - body: '{"TableName":"gotabledtlot4b2qfkop","odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables/@Element"}' - headers: - Content-Type: - - application/json;odata=minimalmetadata - Date: - - Mon, 05 Apr 2021 05:02:40 GMT - Etag: - - W/"datetime'2021-04-05T05%3A02%3A40.1485832Z'" - Location: - - https://chrisstablesprim.table.cosmos.azure.com/Tables('gotabledtlot4b2qfkop') - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - 0c4ccc90-a38a-47db-b904-ec327ee3f600 - status: 201 Created - code: 201 - duration: "" -- request: - body: '{"BoolProp":true,"IntProp":1,"PartitionKey":"partition","RowKey":"1","StringProp":"some - string 1"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "98" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - Prefer: - - return-no-content - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Mon, 05 Apr 2021 05:02:40 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/gotabledtlot4b2qfkop - method: POST - response: - body: "" - headers: - Content-Length: - - "0" - Date: - - Mon, 05 Apr 2021 05:02:40 GMT - Etag: - - W/"datetime'2021-04-05T05%3A02%3A40.7371784Z'" - Location: - - https://chrisstablesprim.table.cosmos.azure.com/gotabledtlot4b2qfkop(PartitionKey='partition',RowKey='1') - Preference-Applied: - - return-no-content - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - 40cfa5d5-3867-469b-a5fe-aa61bfdded39 - status: 204 No Content - code: 204 - duration: "" -- request: - body: '{"BoolProp":true,"IntProp":2,"PartitionKey":"partition","RowKey":"2","StringProp":"some - string 2"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "98" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - Prefer: - - return-no-content - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Mon, 05 Apr 2021 05:02:40 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/gotabledtlot4b2qfkop - method: POST - response: - body: "" - headers: - Content-Length: - - "0" - Date: - - Mon, 05 Apr 2021 05:02:40 GMT - Etag: - - W/"datetime'2021-04-05T05%3A02%3A40.8410120Z'" - Location: - - https://chrisstablesprim.table.cosmos.azure.com/gotabledtlot4b2qfkop(PartitionKey='partition',RowKey='2') - Preference-Applied: - - return-no-content - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - 3c31aac3-2859-47ad-abd7-8203e7f10b11 - status: 204 No Content - code: 204 - duration: "" -- request: - body: '{"BoolProp":true,"IntProp":3,"PartitionKey":"partition","RowKey":"3","StringProp":"some - string 3"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "98" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - Prefer: - - return-no-content - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Mon, 05 Apr 2021 05:02:41 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/gotabledtlot4b2qfkop - method: POST - response: - body: "" - headers: - Content-Length: - - "0" - Date: - - Mon, 05 Apr 2021 05:02:40 GMT - Etag: - - W/"datetime'2021-04-05T05%3A02%3A40.9537544Z'" - Location: - - https://chrisstablesprim.table.cosmos.azure.com/gotabledtlot4b2qfkop(PartitionKey='partition',RowKey='3') - Preference-Applied: - - return-no-content - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - 0cd7d680-2274-4e93-9b7f-4d44cacff771 - status: 204 No Content - code: 204 - duration: "" -- request: - body: '{"BoolProp":true,"IntProp":4,"PartitionKey":"partition","RowKey":"4","StringProp":"some - string 4"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "98" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - Prefer: - - return-no-content - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Mon, 05 Apr 2021 05:02:41 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/gotabledtlot4b2qfkop - method: POST - response: - body: "" - headers: - Content-Length: - - "0" - Date: - - Mon, 05 Apr 2021 05:02:40 GMT - Etag: - - W/"datetime'2021-04-05T05%3A02%3A41.0579976Z'" - Location: - - https://chrisstablesprim.table.cosmos.azure.com/gotabledtlot4b2qfkop(PartitionKey='partition',RowKey='4') - Preference-Applied: - - return-no-content - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - 2c18f6d8-af7f-4533-bf30-9243a8e31e18 - status: 204 No Content - code: 204 - duration: "" -- request: - body: '{"BoolProp":true,"IntProp":5,"PartitionKey":"partition","RowKey":"5","StringProp":"some - string 5"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "98" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - Prefer: - - return-no-content - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Mon, 05 Apr 2021 05:02:41 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/gotabledtlot4b2qfkop - method: POST - response: - body: "" - headers: - Content-Length: - - "0" - Date: - - Mon, 05 Apr 2021 05:02:40 GMT - Etag: - - W/"datetime'2021-04-05T05%3A02%3A41.1676680Z'" - Location: - - https://chrisstablesprim.table.cosmos.azure.com/gotabledtlot4b2qfkop(PartitionKey='partition',RowKey='5') - Preference-Applied: - - return-no-content - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - 6ca39a1d-05ef-4d68-bfc2-5a79a009fdeb - status: 204 No Content - code: 204 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Mon, 05 Apr 2021 05:02:41 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/gotabledtlot4b2qfkop()?%24filter=RowKey+lt+%275%27 - method: GET - response: - body: '{"value":[{"odata.etag":"W/\"datetime''2021-04-05T05%3A02%3A40.7371784Z''\"","BoolProp":true,"IntProp":1,"PartitionKey":"partition","RowKey":"1","StringProp":"some - string 1","Timestamp":"2021-04-05T05:02:40.7371784Z"},{"odata.etag":"W/\"datetime''2021-04-05T05%3A02%3A40.8410120Z''\"","BoolProp":true,"IntProp":2,"PartitionKey":"partition","RowKey":"2","StringProp":"some - string 2","Timestamp":"2021-04-05T05:02:40.8410120Z"},{"odata.etag":"W/\"datetime''2021-04-05T05%3A02%3A40.9537544Z''\"","BoolProp":true,"IntProp":3,"PartitionKey":"partition","RowKey":"3","StringProp":"some - string 3","Timestamp":"2021-04-05T05:02:40.9537544Z"},{"odata.etag":"W/\"datetime''2021-04-05T05%3A02%3A41.0579976Z''\"","BoolProp":true,"IntProp":4,"PartitionKey":"partition","RowKey":"4","StringProp":"some - string 4","Timestamp":"2021-04-05T05:02:41.0579976Z"}],"odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#gotabledtlot4b2qfkop"}' - headers: - Content-Type: - - application/json;odata=minimalmetadata - Date: - - Mon, 05 Apr 2021 05:02:40 GMT - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - 98466a7e-727a-4e2d-8f48-37039dae8f64 - status: 200 OK - code: 200 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json - Authorization: - - sanitized - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Mon, 05 Apr 2021 05:02:41 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/Tables('gotabledtlot4b2qfkop') - method: DELETE - response: - body: "" - headers: - Content-Length: - - "0" - Date: - - Mon, 05 Apr 2021 05:02:41 GMT - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - d7fa3ec7-64ad-43a3-8444-9f567b156391 - status: 204 No Content - code: 204 - duration: "" diff --git a/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestServiceErrors-variables.yaml b/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestServiceErrors-variables.yaml deleted file mode 100644 index be617c45b1f0..000000000000 --- a/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestServiceErrors-variables.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -COSMOS_TABLES_ENDPOINT_SUFFIX: cosmos.azure.com -TABLES_COSMOS_ACCOUNT_NAME: chrisstablesprim -TABLES_PRIMARY_COSMOS_ACCOUNT_KEY: Kg== -randomSeed: "1617580014" diff --git a/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestServiceErrors.yaml b/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestServiceErrors.yaml deleted file mode 100644 index 0a52371c64d2..000000000000 --- a/sdk/tables/aztables/recordings/TestTableClient_Cosmos/TestServiceErrors.yaml +++ /dev/null @@ -1,113 +0,0 @@ ---- -version: 1 -interactions: -- request: - body: '{"TableName":"gotable85g6eby7icg1v"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "36" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 23:46:54 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/Tables - method: POST - response: - body: '{"TableName":"gotable85g6eby7icg1v","odata.metadata":"https://chrisstablesprim.table.cosmos.azure.com/$metadata#Tables/@Element"}' - headers: - Content-Type: - - application/json;odata=minimalmetadata - Date: - - Sun, 04 Apr 2021 23:46:54 GMT - Etag: - - W/"datetime'2021-04-04T23%3A46%3A54.7914760Z'" - Location: - - https://chrisstablesprim.table.cosmos.azure.com/Tables('gotable85g6eby7icg1v') - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - 947f9642-3c9b-475a-b3a0-6c04b3c2d40b - status: 201 Created - code: 201 - duration: "" -- request: - body: '{"TableName":"gotable85g6eby7icg1v"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "36" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 23:46:55 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/Tables - method: POST - response: - body: "{\"odata.error\":{\"code\":\"TableAlreadyExists\",\"message\":{\"lang\":\"en-us\",\"value\":\"The - specified table already exists.\\nRequestID:58f7ef4b-3378-4612-8f88-7fad883916de\\n\"}}}\r\n" - headers: - Content-Type: - - application/json;odata=minimalmetadata - Date: - - Sun, 04 Apr 2021 23:46:54 GMT - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - 58f7ef4b-3378-4612-8f88-7fad883916de - status: 409 Conflict - code: 409 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json - Authorization: - - sanitized - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 23:46:55 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.cosmos.azure.com/Tables('gotable85g6eby7icg1v') - method: DELETE - response: - body: "" - headers: - Content-Length: - - "0" - Date: - - Sun, 04 Apr 2021 23:46:54 GMT - Server: - - Microsoft-HTTPAPI/2.0 - X-Ms-Request-Id: - - 40da51e2-3c50-4a09-a6e9-78663d0215c4 - status: 204 No Content - code: 204 - duration: "" diff --git a/sdk/tables/aztables/recordings/TestTableClient_Storage/TestAddComplexEntity-variables.yaml b/sdk/tables/aztables/recordings/TestTableClient_Storage/TestAddComplexEntity-variables.yaml deleted file mode 100644 index f86a77d88694..000000000000 --- a/sdk/tables/aztables/recordings/TestTableClient_Storage/TestAddComplexEntity-variables.yaml +++ /dev/null @@ -1,6 +0,0 @@ ---- -STORAGE_ENDPOINT_SUFFIX: core.windows.net -TABLES_PRIMARY_STORAGE_ACCOUNT_KEY: Kg== -TABLES_STORAGE_ACCOUNT_NAME: chrisstablesprim -now: "2021-04-10T19:18:38.5403201-05:00" -randomSeed: "1618100317" diff --git a/sdk/tables/aztables/recordings/TestTableClient_Storage/TestAddComplexEntity.yaml b/sdk/tables/aztables/recordings/TestTableClient_Storage/TestAddComplexEntity.yaml deleted file mode 100644 index 78e8e8f28f88..000000000000 --- a/sdk/tables/aztables/recordings/TestTableClient_Storage/TestAddComplexEntity.yaml +++ /dev/null @@ -1,139 +0,0 @@ ---- -version: 1 -interactions: -- request: - body: '{"TableName":"gotableseqkydnlewbop"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "36" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 11 Apr 2021 00:18:37 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/Tables - method: POST - response: - body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#Tables/@Element","TableName":"gotableseqkydnlewbop"}' - headers: - Cache-Control: - - no-cache - Content-Type: - - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 - Date: - - Sun, 11 Apr 2021 00:18:38 GMT - Location: - - https://chrisstablesprim.table.core.windows.net/Tables('gotableseqkydnlewbop') - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - 91267bb0-7002-0034-4468-2e07dc000000 - X-Ms-Version: - - "2019-02-02" - status: 201 Created - code: 201 - duration: "" -- request: - body: '{"PartitionKey":"partition","RowKey":"row","SomeBinaryProperty":"c29tZSBieXRlcw==","SomeBinaryProperty@odata.type":"Edm.Binary","SomeDateProperty":"2021-04-11T00:18:38.5403201Z","SomeDateProperty@odata.type":"Edm.DateTime","SomeDoubleProperty0":1,"SomeDoubleProperty0@odata.type":"Edm.Double","SomeDoubleProperty1":1.2345,"SomeDoubleProperty1@odata.type":"Edm.Double","SomeGuidProperty":"bc08bdf6-10bd-4b3e-612f-62de19f57821","SomeGuidProperty@odata.type":"Edm.Guid","SomeInt64Property":"9223372036854775807","SomeInt64Property@odata.type":"Edm.Int64","SomeIntProperty":42,"SomePtrStringProperty":"some - pointer to string","SomeStringProperty":"some string"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "657" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - Prefer: - - return-no-content - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 11 Apr 2021 00:18:38 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/gotableseqkydnlewbop - method: POST - response: - body: "" - headers: - Cache-Control: - - no-cache - Content-Length: - - "0" - Dataserviceid: - - https://chrisstablesprim.table.core.windows.net/gotableseqkydnlewbop(PartitionKey='partition',RowKey='row') - Date: - - Sun, 11 Apr 2021 00:18:38 GMT - Etag: - - W/"datetime'2021-04-11T00%3A18%3A38.2407207Z'" - Location: - - https://chrisstablesprim.table.core.windows.net/gotableseqkydnlewbop(PartitionKey='partition',RowKey='row') - Preference-Applied: - - return-no-content - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - 91267bbe-7002-0034-5068-2e07dc000000 - X-Ms-Version: - - "2019-02-02" - status: 204 No Content - code: 204 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json - Authorization: - - sanitized - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 11 Apr 2021 00:18:38 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/Tables('gotableseqkydnlewbop') - method: DELETE - response: - body: "" - headers: - Cache-Control: - - no-cache - Content-Length: - - "0" - Date: - - Sun, 11 Apr 2021 00:18:38 GMT - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - 91267bc3-7002-0034-5568-2e07dc000000 - X-Ms-Version: - - "2019-02-02" - status: 204 No Content - code: 204 - duration: "" diff --git a/sdk/tables/aztables/recordings/TestTableClient_Storage/TestAddEntity-variables.yaml b/sdk/tables/aztables/recordings/TestTableClient_Storage/TestAddEntity-variables.yaml deleted file mode 100644 index b2ce8f9f7145..000000000000 --- a/sdk/tables/aztables/recordings/TestTableClient_Storage/TestAddEntity-variables.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -STORAGE_ENDPOINT_SUFFIX: core.windows.net -TABLES_PRIMARY_STORAGE_ACCOUNT_KEY: Kg== -TABLES_STORAGE_ACCOUNT_NAME: chrisstablesprim -randomSeed: "1617580855" diff --git a/sdk/tables/aztables/recordings/TestTableClient_Storage/TestAddEntity.yaml b/sdk/tables/aztables/recordings/TestTableClient_Storage/TestAddEntity.yaml deleted file mode 100644 index e5b71baad0b6..000000000000 --- a/sdk/tables/aztables/recordings/TestTableClient_Storage/TestAddEntity.yaml +++ /dev/null @@ -1,139 +0,0 @@ ---- -version: 1 -interactions: -- request: - body: '{"TableName":"gotableldjhskq166plj"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "36" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Mon, 05 Apr 2021 00:00:55 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/Tables - method: POST - response: - body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#Tables/@Element","TableName":"gotableldjhskq166plj"}' - headers: - Cache-Control: - - no-cache - Content-Type: - - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 - Date: - - Mon, 05 Apr 2021 00:00:55 GMT - Location: - - https://chrisstablesprim.table.core.windows.net/Tables('gotableldjhskq166plj') - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - 204673eb-b002-003b-64ae-2971b0000000 - X-Ms-Version: - - "2019-02-02" - status: 201 Created - code: 201 - duration: "" -- request: - body: '{"BoolProp":true,"IntProp":1,"PartitionKey":"partition","RowKey":"1","StringProp":"some - string 1"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "98" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - Prefer: - - return-no-content - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Mon, 05 Apr 2021 00:00:55 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/gotableldjhskq166plj - method: POST - response: - body: "" - headers: - Cache-Control: - - no-cache - Content-Length: - - "0" - Dataserviceid: - - https://chrisstablesprim.table.core.windows.net/gotableldjhskq166plj(PartitionKey='partition',RowKey='1') - Date: - - Mon, 05 Apr 2021 00:00:55 GMT - Etag: - - W/"datetime'2021-04-05T00%3A00%3A55.7477359Z'" - Location: - - https://chrisstablesprim.table.core.windows.net/gotableldjhskq166plj(PartitionKey='partition',RowKey='1') - Preference-Applied: - - return-no-content - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - 204673f0-b002-003b-67ae-2971b0000000 - X-Ms-Version: - - "2019-02-02" - status: 204 No Content - code: 204 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json - Authorization: - - sanitized - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Mon, 05 Apr 2021 00:00:55 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/Tables('gotableldjhskq166plj') - method: DELETE - response: - body: "" - headers: - Cache-Control: - - no-cache - Content-Length: - - "0" - Date: - - Mon, 05 Apr 2021 00:00:55 GMT - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - 204673f1-b002-003b-68ae-2971b0000000 - X-Ms-Version: - - "2019-02-02" - status: 204 No Content - code: 204 - duration: "" diff --git a/sdk/tables/aztables/recordings/TestTableClient_Storage/TestCreateTable-variables.yaml b/sdk/tables/aztables/recordings/TestTableClient_Storage/TestCreateTable-variables.yaml deleted file mode 100644 index db82b723a5c5..000000000000 --- a/sdk/tables/aztables/recordings/TestTableClient_Storage/TestCreateTable-variables.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -STORAGE_ENDPOINT_SUFFIX: core.windows.net -TABLES_PRIMARY_STORAGE_ACCOUNT_KEY: Kg== -TABLES_STORAGE_ACCOUNT_NAME: chrisstablesprim -randomSeed: "1617573288" diff --git a/sdk/tables/aztables/recordings/TestTableClient_Storage/TestCreateTable.yaml b/sdk/tables/aztables/recordings/TestTableClient_Storage/TestCreateTable.yaml deleted file mode 100644 index 6ef28bf11ac7..000000000000 --- a/sdk/tables/aztables/recordings/TestTableClient_Storage/TestCreateTable.yaml +++ /dev/null @@ -1,85 +0,0 @@ ---- -version: 1 -interactions: -- request: - body: '{"TableName":"gotable9uourkrfkri2m"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "36" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:48 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/Tables - method: POST - response: - body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#Tables/@Element","TableName":"gotable9uourkrfkri2m"}' - headers: - Cache-Control: - - no-cache - Content-Type: - - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 - Date: - - Sun, 04 Apr 2021 21:54:48 GMT - Location: - - https://chrisstablesprim.table.core.windows.net/Tables('gotable9uourkrfkri2m') - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - aa171ae1-c002-0053-399d-291720000000 - X-Ms-Version: - - "2019-02-02" - status: 201 Created - code: 201 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json - Authorization: - - sanitized - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 21:54:48 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/Tables('gotable9uourkrfkri2m') - method: DELETE - response: - body: "" - headers: - Cache-Control: - - no-cache - Content-Length: - - "0" - Date: - - Sun, 04 Apr 2021 21:54:48 GMT - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - aa171aec-c002-0053-419d-291720000000 - X-Ms-Version: - - "2019-02-02" - status: 204 No Content - code: 204 - duration: "" diff --git a/sdk/tables/aztables/recordings/TestTableClient_Storage/TestQuerySimpleEntity-variables.yaml b/sdk/tables/aztables/recordings/TestTableClient_Storage/TestQuerySimpleEntity-variables.yaml deleted file mode 100644 index 7a6b1b1ab41d..000000000000 --- a/sdk/tables/aztables/recordings/TestTableClient_Storage/TestQuerySimpleEntity-variables.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -STORAGE_ENDPOINT_SUFFIX: core.windows.net -TABLES_PRIMARY_STORAGE_ACCOUNT_KEY: Kg== -TABLES_STORAGE_ACCOUNT_NAME: chrisstablesprim -randomSeed: "1617598958" diff --git a/sdk/tables/aztables/recordings/TestTableClient_Storage/TestQuerySimpleEntity.yaml b/sdk/tables/aztables/recordings/TestTableClient_Storage/TestQuerySimpleEntity.yaml deleted file mode 100644 index 1735178553e0..000000000000 --- a/sdk/tables/aztables/recordings/TestTableClient_Storage/TestQuerySimpleEntity.yaml +++ /dev/null @@ -1,398 +0,0 @@ ---- -version: 1 -interactions: -- request: - body: '{"TableName":"gotablev9ymy16fzote2"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "36" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Mon, 05 Apr 2021 05:02:38 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/Tables - method: POST - response: - body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#Tables/@Element","TableName":"gotablev9ymy16fzote2"}' - headers: - Cache-Control: - - no-cache - Content-Type: - - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 - Date: - - Mon, 05 Apr 2021 05:02:37 GMT - Location: - - https://chrisstablesprim.table.core.windows.net/Tables('gotablev9ymy16fzote2') - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - 95cfebe3-e002-0019-49d8-29b4af000000 - X-Ms-Version: - - "2019-02-02" - status: 201 Created - code: 201 - duration: "" -- request: - body: '{"BoolProp":true,"IntProp":1,"PartitionKey":"partition","RowKey":"1","StringProp":"some - string 1"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "98" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - Prefer: - - return-no-content - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Mon, 05 Apr 2021 05:02:38 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2 - method: POST - response: - body: "" - headers: - Cache-Control: - - no-cache - Content-Length: - - "0" - Dataserviceid: - - https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2(PartitionKey='partition',RowKey='1') - Date: - - Mon, 05 Apr 2021 05:02:37 GMT - Etag: - - W/"datetime'2021-04-05T05%3A02%3A38.4885381Z'" - Location: - - https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2(PartitionKey='partition',RowKey='1') - Preference-Applied: - - return-no-content - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - 95cfebec-e002-0019-50d8-29b4af000000 - X-Ms-Version: - - "2019-02-02" - status: 204 No Content - code: 204 - duration: "" -- request: - body: '{"BoolProp":true,"IntProp":2,"PartitionKey":"partition","RowKey":"2","StringProp":"some - string 2"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "98" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - Prefer: - - return-no-content - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Mon, 05 Apr 2021 05:02:38 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2 - method: POST - response: - body: "" - headers: - Cache-Control: - - no-cache - Content-Length: - - "0" - Dataserviceid: - - https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2(PartitionKey='partition',RowKey='2') - Date: - - Mon, 05 Apr 2021 05:02:37 GMT - Etag: - - W/"datetime'2021-04-05T05%3A02%3A38.5946142Z'" - Location: - - https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2(PartitionKey='partition',RowKey='2') - Preference-Applied: - - return-no-content - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - 95cfebf1-e002-0019-55d8-29b4af000000 - X-Ms-Version: - - "2019-02-02" - status: 204 No Content - code: 204 - duration: "" -- request: - body: '{"BoolProp":true,"IntProp":3,"PartitionKey":"partition","RowKey":"3","StringProp":"some - string 3"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "98" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - Prefer: - - return-no-content - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Mon, 05 Apr 2021 05:02:38 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2 - method: POST - response: - body: "" - headers: - Cache-Control: - - no-cache - Content-Length: - - "0" - Dataserviceid: - - https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2(PartitionKey='partition',RowKey='3') - Date: - - Mon, 05 Apr 2021 05:02:38 GMT - Etag: - - W/"datetime'2021-04-05T05%3A02%3A38.6866808Z'" - Location: - - https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2(PartitionKey='partition',RowKey='3') - Preference-Applied: - - return-no-content - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - 95cfebf3-e002-0019-57d8-29b4af000000 - X-Ms-Version: - - "2019-02-02" - status: 204 No Content - code: 204 - duration: "" -- request: - body: '{"BoolProp":true,"IntProp":4,"PartitionKey":"partition","RowKey":"4","StringProp":"some - string 4"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "98" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - Prefer: - - return-no-content - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Mon, 05 Apr 2021 05:02:38 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2 - method: POST - response: - body: "" - headers: - Cache-Control: - - no-cache - Content-Length: - - "0" - Dataserviceid: - - https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2(PartitionKey='partition',RowKey='4') - Date: - - Mon, 05 Apr 2021 05:02:38 GMT - Etag: - - W/"datetime'2021-04-05T05%3A02%3A38.7727417Z'" - Location: - - https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2(PartitionKey='partition',RowKey='4') - Preference-Applied: - - return-no-content - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - 95cfebf5-e002-0019-59d8-29b4af000000 - X-Ms-Version: - - "2019-02-02" - status: 204 No Content - code: 204 - duration: "" -- request: - body: '{"BoolProp":true,"IntProp":5,"PartitionKey":"partition","RowKey":"5","StringProp":"some - string 5"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "98" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - Prefer: - - return-no-content - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Mon, 05 Apr 2021 05:02:38 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2 - method: POST - response: - body: "" - headers: - Cache-Control: - - no-cache - Content-Length: - - "0" - Dataserviceid: - - https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2(PartitionKey='partition',RowKey='5') - Date: - - Mon, 05 Apr 2021 05:02:38 GMT - Etag: - - W/"datetime'2021-04-05T05%3A02%3A38.8487963Z'" - Location: - - https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2(PartitionKey='partition',RowKey='5') - Preference-Applied: - - return-no-content - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - 95cfebfb-e002-0019-5cd8-29b4af000000 - X-Ms-Version: - - "2019-02-02" - status: 204 No Content - code: 204 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Mon, 05 Apr 2021 05:02:39 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/gotablev9ymy16fzote2()?%24filter=RowKey+lt+%275%27 - method: GET - response: - body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#gotablev9ymy16fzote2","value":[{"odata.etag":"W/\"datetime''2021-04-05T05%3A02%3A38.4885381Z''\"","PartitionKey":"partition","RowKey":"1","Timestamp":"2021-04-05T05:02:38.4885381Z","BoolProp":true,"IntProp":1,"StringProp":"some - string 1"},{"odata.etag":"W/\"datetime''2021-04-05T05%3A02%3A38.5946142Z''\"","PartitionKey":"partition","RowKey":"2","Timestamp":"2021-04-05T05:02:38.5946142Z","BoolProp":true,"IntProp":2,"StringProp":"some - string 2"},{"odata.etag":"W/\"datetime''2021-04-05T05%3A02%3A38.6866808Z''\"","PartitionKey":"partition","RowKey":"3","Timestamp":"2021-04-05T05:02:38.6866808Z","BoolProp":true,"IntProp":3,"StringProp":"some - string 3"},{"odata.etag":"W/\"datetime''2021-04-05T05%3A02%3A38.7727417Z''\"","PartitionKey":"partition","RowKey":"4","Timestamp":"2021-04-05T05:02:38.7727417Z","BoolProp":true,"IntProp":4,"StringProp":"some - string 4"}]}' - headers: - Cache-Control: - - no-cache - Content-Type: - - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 - Date: - - Mon, 05 Apr 2021 05:02:38 GMT - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - 95cfebfe-e002-0019-5ed8-29b4af000000 - X-Ms-Version: - - "2019-02-02" - status: 200 OK - code: 200 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json - Authorization: - - sanitized - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Mon, 05 Apr 2021 05:02:39 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/Tables('gotablev9ymy16fzote2') - method: DELETE - response: - body: "" - headers: - Cache-Control: - - no-cache - Content-Length: - - "0" - Date: - - Mon, 05 Apr 2021 05:02:38 GMT - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - 95cfec00-e002-0019-60d8-29b4af000000 - X-Ms-Version: - - "2019-02-02" - status: 204 No Content - code: 204 - duration: "" diff --git a/sdk/tables/aztables/recordings/TestTableClient_Storage/TestServiceErrors-variables.yaml b/sdk/tables/aztables/recordings/TestTableClient_Storage/TestServiceErrors-variables.yaml deleted file mode 100644 index db3e9cbbe8a7..000000000000 --- a/sdk/tables/aztables/recordings/TestTableClient_Storage/TestServiceErrors-variables.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -STORAGE_ENDPOINT_SUFFIX: core.windows.net -TABLES_PRIMARY_STORAGE_ACCOUNT_KEY: Kg== -TABLES_STORAGE_ACCOUNT_NAME: chrisstablesprim -randomSeed: "1617580013" diff --git a/sdk/tables/aztables/recordings/TestTableClient_Storage/TestServiceErrors.yaml b/sdk/tables/aztables/recordings/TestTableClient_Storage/TestServiceErrors.yaml deleted file mode 100644 index 65a3e042f9f4..000000000000 --- a/sdk/tables/aztables/recordings/TestTableClient_Storage/TestServiceErrors.yaml +++ /dev/null @@ -1,129 +0,0 @@ ---- -version: 1 -interactions: -- request: - body: '{"TableName":"gotable4gghmbc0umbca"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "36" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 23:46:53 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/Tables - method: POST - response: - body: '{"odata.metadata":"https://chrisstablesprim.table.core.windows.net/$metadata#Tables/@Element","TableName":"gotable4gghmbc0umbca"}' - headers: - Cache-Control: - - no-cache - Content-Type: - - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 - Date: - - Sun, 04 Apr 2021 23:46:53 GMT - Location: - - https://chrisstablesprim.table.core.windows.net/Tables('gotable4gghmbc0umbca') - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - 89afb2ba-b002-0066-1aac-297b34000000 - X-Ms-Version: - - "2019-02-02" - status: 201 Created - code: 201 - duration: "" -- request: - body: '{"TableName":"gotable4gghmbc0umbca"}' - form: {} - headers: - Accept: - - application/json;odata=minimalmetadata - Authorization: - - sanitized - Content-Length: - - "36" - Content-Type: - - application/json - Dataserviceversion: - - "3.0" - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 23:46:54 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/Tables - method: POST - response: - body: '{"odata.error":{"code":"TableAlreadyExists","message":{"lang":"en-US","value":"The - table specified already exists.\nRequestId:89afb2c5-b002-0066-23ac-297b34000000\nTime:2021-04-04T23:46:53.9829008Z"}}}' - headers: - Cache-Control: - - no-cache - Content-Type: - - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 - Date: - - Sun, 04 Apr 2021 23:46:53 GMT - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - 89afb2c5-b002-0066-23ac-297b34000000 - X-Ms-Version: - - "2019-02-02" - status: 409 Conflict - code: 409 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json - Authorization: - - sanitized - User-Agent: - - azsdk-go-tables/ azsdk-go-tables/ azcore/v0.13.4 (go1.16.2; - Windows_NT) - X-Ms-Date: - - Sun, 04 Apr 2021 23:46:54 GMT - X-Ms-Version: - - "2019-02-02" - url: https://chrisstablesprim.table.core.windows.net/Tables('gotable4gghmbc0umbca') - method: DELETE - response: - body: "" - headers: - Cache-Control: - - no-cache - Content-Length: - - "0" - Date: - - Sun, 04 Apr 2021 23:46:53 GMT - Server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - X-Content-Type-Options: - - nosniff - X-Ms-Request-Id: - - 89afb2cd-b002-0066-2aac-297b34000000 - X-Ms-Version: - - "2019-02-02" - status: 204 No Content - code: 204 - duration: "" diff --git a/sdk/tables/aztables/tableClient.go b/sdk/tables/aztables/tableClient.go index 6f253d6f0767..edc74ece6075 100644 --- a/sdk/tables/aztables/tableClient.go +++ b/sdk/tables/aztables/tableClient.go @@ -5,70 +5,35 @@ package aztables import ( "context" - "github.com/Azure/azure-sdk-for-go/sdk/azcore" - "github.com/Azure/azure-sdk-for-go/sdk/internal/runtime" ) // A TableClient represents a URL to an Azure Storage blob; the blob may be a block blob, append blob, or page blob. type TableClient struct { - client *tableClient - service *TableServiceClient - cred SharedKeyCredential - name string + client *tableClient + cred SharedKeyCredential } // NewTableClient creates a TableClient object using the specified URL and request policy pipeline. -func NewTableClient(tableName string, serviceURL string, cred azcore.Credential, options *TableClientOptions) (*TableClient, error) { - s, err := NewTableServiceClient(serviceURL, cred, options) - return s.GetTableClient(tableName), err -} - -func (t *TableClient) Name() string { - return t.name -} - -// Create creates the table with the name specified in NewTableClient -func (t *TableClient) Create(ctx context.Context) (*TableResponseResponse, *runtime.ResponseError) { - return t.service.Create(ctx, t.name) -} +func NewTableClient(serviceURL string, cred azcore.Credential, options *TableClientOptions) (*TableClient, error) { + con := newConnection(serviceURL, cred, options.getConnectionOptions()) -// Delete deletes the current table -func (t *TableClient) Delete(ctx context.Context) (*TableDeleteResponse, *runtime.ResponseError) { - return t.service.Delete(ctx, t.name) -} - -// Query queries the tables using the specified QueryOptions -func (t *TableClient) Query(queryOptions QueryOptions) TableEntityQueryResponsePager { - return &tableEntityQueryResponsePager{tableClient: t, queryOptions: &queryOptions, tableQueryOptions: &TableQueryEntitiesOptions{}} -} + c, _ := cred.(*SharedKeyCredential) -func (t *TableClient) QueryAsStruct(opt QueryOptions, s FromMapper) StructEntityQueryResponsePager { - return &structQueryResponsePager{mapper: s, tableClient: t, queryOptions: &opt, tableQueryOptions: &TableQueryEntitiesOptions{}} + return &TableClient{client: &tableClient{con}, cred: *c}, nil } -// AddMapEntity Creates an entity from a map value. -func (t *TableClient) AddMapEntity(ctx context.Context, entity *map[string]interface{}) (*TableInsertEntityResponse, *runtime.ResponseError) { - resp, err := t.client.InsertEntity(ctx, t.name, &TableInsertEntityOptions{TableEntityProperties: entity, ResponsePreference: ResponseFormatReturnNoContent.ToPtr()}, &QueryOptions{}) - if err == nil { - insertResp := resp.(TableInsertEntityResponse) - return &insertResp, nil +// Create +func (t TableClient) Create(ctx context.Context, name string) (TableResponseResponse, error) { + resp, err := t.client.Create(ctx, TableProperties{&name}, nil, nil) + if resp == nil { + return TableResponseResponse{}, err } else { - return nil, convertErr(err) + return resp.(TableResponseResponse), err } } -// AddEntity creates an entity from an arbitrary struct value. -func (t *TableClient) AddEntity(ctx context.Context, entity interface{}) (*TableInsertEntityResponse, *runtime.ResponseError) { - entmap, err := toMap(entity) - if err != nil { - return nil, azcore.NewResponseError(err, nil).(*runtime.ResponseError) - } - resp, err := t.client.InsertEntity(ctx, t.name, &TableInsertEntityOptions{TableEntityProperties: entmap, ResponsePreference: ResponseFormatReturnNoContent.ToPtr()}, &QueryOptions{}) - if err == nil { - insertResp := resp.(TableInsertEntityResponse) - return &insertResp, nil - } else { - return nil, convertErr(err) - } +// Delete +func (t TableClient) Delete(ctx context.Context, name string) (TableDeleteResponse, error) { + return t.client.Delete(ctx, name, nil) } diff --git a/sdk/tables/aztables/tableClient_test.go b/sdk/tables/aztables/tableClient_test.go index f3a3ce86dada..0b76e48fd15d 100644 --- a/sdk/tables/aztables/tableClient_test.go +++ b/sdk/tables/aztables/tableClient_test.go @@ -4,163 +4,9 @@ package aztables import ( - "bytes" - "io/ioutil" - "net/http" - "testing" - - "github.com/Azure/azure-sdk-for-go/sdk/internal/runtime" - "github.com/Azure/azure-sdk-for-go/sdk/internal/testframework" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/suite" + chk "gopkg.in/check.v1" // go get gopkg.in/check.v1 ) -type tableClientLiveTests struct { - suite.Suite - endpointType EndpointType - mode testframework.RecordMode -} - -// Hookup to the testing framework -func TestTableClient_Storage(t *testing.T) { - storage := tableClientLiveTests{endpointType: StorageEndpoint, mode: testframework.Playback /* change to Record to re-record tests */} - suite.Run(t, &storage) -} - -// Hookup to the testing framework -func TestTableClient_Cosmos(t *testing.T) { - cosmos := tableClientLiveTests{endpointType: CosmosEndpoint, mode: testframework.Playback /* change to Record to re-record tests */} - suite.Run(t, &cosmos) -} - -func (s *tableClientLiveTests) TestServiceErrors() { - client, delete := s.init(true) - defer delete() - - // Create a duplicate table to produce an error - _, err := client.Create(ctx) - assert.Equal(s.T(), err.RawResponse().StatusCode, http.StatusConflict) -} - -func (s *tableClientLiveTests) TestCreateTable() { - assert := assert.New(s.T()) - client, delete := s.init(false) - defer delete() - - resp, err := client.Create(ctx) - - assert.Nil(err) - assert.Equal(*resp.TableResponse.TableName, client.Name()) -} - -func (s *tableClientLiveTests) TestAddEntity() { - assert := assert.New(s.T()) - client, delete := s.init(true) - defer delete() - - entitiesToCreate := createSimpleEntities(1, "partition") - - for _, e := range *entitiesToCreate { - _, err := client.AddMapEntity(ctx, &e) - assert.Nil(err) - } -} - -func (s *tableClientLiveTests) TestAddComplexEntity() { - assert := assert.New(s.T()) - context := getTestContext(s.T().Name()) - client, delete := s.init(true) - defer delete() - - entitiesToCreate := createComplexEntities(context, 1, "partition") - - for _, e := range *entitiesToCreate { - _, err := client.AddEntity(ctx, &e) - assert.Nilf(err, getStringFromBody(err)) - } -} - -func (s *tableClientLiveTests) TestQuerySimpleEntity() { - assert := assert.New(s.T()) - client, delete := s.init(true) - defer delete() - - // Add 5 entities - entitiesToCreate := createSimpleEntities(5, "partition") - for _, e := range *entitiesToCreate { - _, err := client.AddMapEntity(ctx, &e) - assert.Nil(err) - } - - filter := "RowKey lt '5'" - expectedCount := 4 - var resp TableEntityQueryResponseResponse - pager := client.Query(QueryOptions{Filter: &filter}) - for pager.NextPage(ctx) { - resp = pager.PageResponse() - assert.Equal(len(*resp.TableEntityQueryResponse.Value), expectedCount) - } - resp = pager.PageResponse() - assert.Nil(pager.Err()) - for _, e := range *resp.TableEntityQueryResponse.Value { - _, ok := e[PartitionKey].(string) - assert.True(ok) - _, ok = e[RowKey].(string) - assert.True(ok) - _, ok = e[Timestamp].(string) - assert.True(ok) - _, ok = e[EtagOdata].(string) - assert.True(ok) - _, ok = e["StringProp"].(string) - assert.True(ok) - //TODO: fix when serialization is implemented - _, ok = e["IntProp"].(float64) - assert.True(ok) - _, ok = e["BoolProp"].(bool) - assert.True(ok) - } -} - -// setup the test environment -func (s *tableClientLiveTests) BeforeTest(suite string, test string) { - recordedTestSetup(s.T(), s.T().Name(), s.endpointType, s.mode) -} - -// teardown the test context -func (s *tableClientLiveTests) AfterTest(suite string, test string) { - recordedTestTeardown(s.T().Name()) -} - -func (s *tableClientLiveTests) init(doCreate bool) (*TableClient, func()) { - assert := assert.New(s.T()) - context := getTestContext(s.T().Name()) - tableName, _ := getTableName(context) - client := context.client.GetTableClient(tableName) - if doCreate { - _, err := client.Create(ctx) - if err != nil { - assert.FailNow(getStringFromBody(err)) - } - } - return client, func() { - client.Delete(ctx) - } -} - -func getStringFromBody(e *runtime.ResponseError) string { - if e == nil { - return "Error is nil" - } - r := e.RawResponse() - body := bytes.Buffer{} - b := r.Body - b.Close() - if b != nil { - _, err := body.ReadFrom(b) - if err != nil { - return "" - } - b = ioutil.NopCloser(&body) - } - return body.String() +func (s *aztestsSuite) TestContainerCreateAccessContainer(c *chk.C) { + // TODO } diff --git a/sdk/tables/aztables/tableServiceClient.go b/sdk/tables/aztables/tableServiceClient.go deleted file mode 100644 index 7c9fef74d621..000000000000 --- a/sdk/tables/aztables/tableServiceClient.go +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -package aztables - -import ( - "context" - "errors" - - "github.com/Azure/azure-sdk-for-go/sdk/azcore" - "github.com/Azure/azure-sdk-for-go/sdk/internal/runtime" -) - -// A TableServiceClient represents a URL to an Azure Storage blob; the blob may be a block blob, append blob, or page blob. -type TableServiceClient struct { - client *tableClient - service *serviceClient - cred SharedKeyCredential -} - -// NewTableServiceClient creates a TableClient object using the specified URL and request policy pipeline. -func NewTableServiceClient(serviceURL string, cred azcore.Credential, options *TableClientOptions) (*TableServiceClient, error) { - con := newConnection(serviceURL, cred, options.getConnectionOptions()) - c, _ := cred.(*SharedKeyCredential) - return &TableServiceClient{client: &tableClient{con}, service: &serviceClient{con}, cred: *c}, nil -} - -// Gets a TableClient affinitzed to the specified table name and initialized with the same serviceURL and credentials as this TableServiceClient -func (t *TableServiceClient) GetTableClient(tableName string) *TableClient { - return &TableClient{client: t.client, cred: t.cred, name: tableName, service: t} -} - -// Creates a table with the specified name -func (t *TableServiceClient) Create(ctx context.Context, name string) (*TableResponseResponse, *runtime.ResponseError) { - var r *TableResponseResponse = nil - resp, err := t.client.Create(ctx, TableProperties{&name}, new(TableCreateOptions), new(QueryOptions)) - if err == nil { - tableResp := resp.(TableResponseResponse) - r = &tableResp - } - return r, convertErr(err) -} - -// Deletes a table by name -func (t *TableServiceClient) Delete(ctx context.Context, name string) (*TableDeleteResponse, *runtime.ResponseError) { - resp, err := t.client.Delete(ctx, name, nil) - return &resp, convertErr(err) -} - -// Queries the tables using the specified QueryOptions -func (t *TableServiceClient) QueryTables(queryOptions QueryOptions) TableQueryResponsePager { - return &tableQueryResponsePager{client: t.client, queryOptions: &queryOptions, tableQueryOptions: new(TableQueryOptions)} -} - -func convertErr(err error) *runtime.ResponseError { - var e *runtime.ResponseError - if err == nil || !errors.As(err, &e) { - return nil - } else { - return e - } -} diff --git a/sdk/tables/aztables/tableServiceClient_test.go b/sdk/tables/aztables/tableServiceClient_test.go deleted file mode 100644 index f57f23d60afd..000000000000 --- a/sdk/tables/aztables/tableServiceClient_test.go +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -package aztables - -import ( - "fmt" - "net/http" - "testing" - - "github.com/Azure/azure-sdk-for-go/sdk/internal/testframework" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/suite" -) - -type tableServiceClientLiveTests struct { - suite.Suite - endpointType EndpointType - mode testframework.RecordMode -} - -// Hookup to the testing framework -func TestServiceClient_Storage(t *testing.T) { - storage := tableServiceClientLiveTests{endpointType: StorageEndpoint, mode: testframework.Playback /* change to Record to re-record tests */} - suite.Run(t, &storage) -} - -// Hookup to the testing framework -func TestServiceClient_Cosmos(t *testing.T) { - cosmos := tableServiceClientLiveTests{endpointType: CosmosEndpoint, mode: testframework.Playback /* change to Record to re-record tests */} - suite.Run(t, &cosmos) -} - -func (s *tableServiceClientLiveTests) TestServiceErrors() { - assert := assert.New(s.T()) - context := getTestContext(s.T().Name()) - tableName, err := getTableName(context) - - _, err = context.client.Create(ctx, tableName) - defer context.client.Delete(ctx, tableName) - assert.Nil(err) - - // Create a duplicate table to produce an error - _, svcErr := context.client.Create(ctx, tableName) - assert.Equal(svcErr.RawResponse().StatusCode, http.StatusConflict) -} - -func (s *tableServiceClientLiveTests) TestCreateTable() { - assert := assert.New(s.T()) - context := getTestContext(s.T().Name()) - tableName, err := getTableName(context) - - resp, err := context.client.Create(ctx, tableName) - defer context.client.Delete(ctx, tableName) - - assert.Nil(err) - assert.Equal(*resp.TableResponse.TableName, tableName) -} - -func (s *tableServiceClientLiveTests) TestQueryTable() { - assert := assert.New(s.T()) - context := getTestContext(s.T().Name()) - tableCount := 5 - tableNames := make([]string, tableCount) - prefix1 := "zzza" - prefix2 := "zzzb" - - defer cleanupTables(context, &tableNames) - //create 10 tables with our exected prefix and 1 with a different prefix - for i := 0; i < tableCount; i++ { - if i < (tableCount - 1) { - name, _ := getTableName(context, prefix1) - tableNames[i] = name - } else { - name, _ := getTableName(context, prefix2) - tableNames[i] = name - } - _, err := context.client.Create(ctx, tableNames[i]) - assert.Nil(err) - } - - // Query for tables with no pagination. The filter should exclude one table from the results - filter := fmt.Sprintf("TableName ge '%s' and TableName lt '%s'", prefix1, prefix2) - pager := context.client.QueryTables(QueryOptions{Filter: &filter}) - - resultCount := 0 - for pager.NextPage(ctx) { - resp := pager.PageResponse() - resultCount += len(*resp.TableQueryResponse.Value) - } - - assert.Nil(pager.Err()) - assert.Equal(resultCount, tableCount-1) - - // Query for tables with pagination - top := int32(2) - pager = context.client.QueryTables(QueryOptions{Filter: &filter, Top: &top}) - - resultCount = 0 - pageCount := 0 - for pager.NextPage(ctx) { - resp := pager.PageResponse() - resultCount += len(*resp.TableQueryResponse.Value) - pageCount++ - } - - assert.Nil(pager.Err()) - assert.Equal(resultCount, tableCount-1) - assert.Equal(pageCount, int(top)) -} - -func (s *tableServiceClientLiveTests) BeforeTest(suite string, test string) { - // setup the test environment - recordedTestSetup(s.T(), s.T().Name(), s.endpointType, s.mode) -} - -func (s *tableServiceClientLiveTests) AfterTest(suite string, test string) { - // teardown the test context - recordedTestTeardown(s.T().Name()) -} diff --git a/sdk/tables/aztables/zc_client_options.go b/sdk/tables/aztables/zc_client_options.go index f0a7200fd141..cf24278fd2d2 100644 --- a/sdk/tables/aztables/zc_client_options.go +++ b/sdk/tables/aztables/zc_client_options.go @@ -23,7 +23,7 @@ func (o *TableClientOptions) getConnectionOptions() *connectionOptions { return &connectionOptions{ HTTPClient: o.HTTPClient, - Retry: o.Retry, - Telemetry: o.Telemetry, + Retry: o.Retry, + Telemetry: o.Telemetry, } -} +} \ No newline at end of file diff --git a/sdk/tables/aztables/zc_tableConstants.go b/sdk/tables/aztables/zc_tableConstants.go deleted file mode 100644 index e48f9e2b60b9..000000000000 --- a/sdk/tables/aztables/zc_tableConstants.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -package aztables - -const ( - Timestamp = "Timestamp" - PartitionKey = "PartitionKey" - RowKey = "RowKey" - EtagOdata = "odata.etag" - ETag = "ETag" - OdataMetadata = "odata.metadata" - OdataType = "@odata.type" - EdmBinary = "Edm.Binary" - EdmBoolean = "Emd.Boolean" - EdmDateTime = "Edm.DateTime" - EdmDouble = "Edm.Double" - EdmGuid = "Edm.Guid" - EdmInt32 = "Edm.Int32" - EdmInt64 = "Edm.Int64" - Edm = "Edm.String" - ISO8601 = "2006-01-02T15:04:05.9999999Z" -) diff --git a/sdk/tables/aztables/zc_table_pagers.go b/sdk/tables/aztables/zc_table_pagers.go deleted file mode 100644 index 1f6a11afe647..000000000000 --- a/sdk/tables/aztables/zc_table_pagers.go +++ /dev/null @@ -1,442 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -package aztables - -import ( - "context" - "encoding/base64" - "errors" - "fmt" - "net/http" - "reflect" - "strconv" - "strings" - "time" - - "github.com/Azure/azure-sdk-for-go/sdk/internal/uuid" -) - -// Pager for Table entity queries -type TableEntityQueryResponsePager interface { - // NextPage returns true if the pager advanced to the next page. - // Returns false if there are no more pages or an error occurred. - NextPage(context.Context) bool - - // Page returns the current TableQueryResponseResponse. - PageResponse() TableEntityQueryResponseResponse - - // Err returns the last error encountered while paging. - Err() error -} - -type StructEntityQueryResponsePager interface { - NextPage(context.Context) bool - PageResponse() StructQueryResponseResponse - Err() error -} - -type StructQueryResponseResponse struct { - // ClientRequestID contains the information returned from the x-ms-client-request-id header response. - ClientRequestID *string - - // Date contains the information returned from the Date header response. - Date *time.Time - - // ETag contains the information returned from the ETag header response. - ETag *string - - // RawResponse contains the underlying HTTP response. - RawResponse *http.Response - - // RequestID contains the information returned from the x-ms-request-id header response. - RequestID *string - - // The properties for the table entity query response. - StructQueryResponse *StructQueryResponse - - // Version contains the information returned from the x-ms-version header response. - Version *string - - // XMSContinuationNextPartitionKey contains the information returned from the x-ms-continuation-NextPartitionKey header response. - XMSContinuationNextPartitionKey *string - - // XMSContinuationNextRowKey contains the information returned from the x-ms-continuation-NextRowKey header response. - XMSContinuationNextRowKey *string -} - -type StructQueryResponse struct { - // The metadata response of the table. - OdataMetadata *string `json:"odata.metadata,omitempty"` - - // List of table entities. - Value *[]interface{} `json:"value,omitempty"` -} - -type tableEntityQueryResponsePager struct { - tableClient *TableClient - current *TableEntityQueryResponseResponse - tableQueryOptions *TableQueryEntitiesOptions - queryOptions *QueryOptions - err error -} - -func (p *tableEntityQueryResponsePager) NextPage(ctx context.Context) bool { - if p.err != nil || (p.current != nil && p.current.XMSContinuationNextPartitionKey == nil && p.current.XMSContinuationNextRowKey == nil) { - return false - } - var resp TableEntityQueryResponseResponse - resp, p.err = p.tableClient.client.QueryEntities(ctx, p.tableClient.name, p.tableQueryOptions, p.queryOptions) - castAndRemoveAnnotationsSlice(resp.TableEntityQueryResponse.Value) - p.current = &resp - p.tableQueryOptions.NextPartitionKey = resp.XMSContinuationNextPartitionKey - p.tableQueryOptions.NextRowKey = resp.XMSContinuationNextRowKey - return p.err == nil && resp.TableEntityQueryResponse.Value != nil && len(*resp.TableEntityQueryResponse.Value) > 0 -} - -func (p *tableEntityQueryResponsePager) PageResponse() TableEntityQueryResponseResponse { - return *p.current -} - -func (p *tableEntityQueryResponsePager) Err() error { - return p.err -} - -type structQueryResponsePager struct { - mapper FromMapper - tableClient *TableClient - current *StructQueryResponseResponse - tableQueryOptions *TableQueryEntitiesOptions - queryOptions *QueryOptions - err error -} - -func (p *structQueryResponsePager) NextPage(ctx context.Context) bool { - if p.err != nil || (p.current != nil && p.current.XMSContinuationNextPartitionKey == nil && p.current.XMSContinuationNextRowKey == nil) { - return false - } - var resp TableEntityQueryResponseResponse - resp, p.err = p.tableClient.client.QueryEntities(ctx, p.tableClient.name, p.tableQueryOptions, p.queryOptions) - castAndRemoveAnnotationsSlice(resp.TableEntityQueryResponse.Value) - //p.current = &resp - r := make([]interface{}, 0, len(*resp.TableEntityQueryResponse.Value)) - for _, e := range *resp.TableEntityQueryResponse.Value { - r = append(r, p.mapper.FromMap(&e)) - } - p.current = &StructQueryResponseResponse{StructQueryResponse: &StructQueryResponse{Value: &r}} - p.tableQueryOptions.NextPartitionKey = resp.XMSContinuationNextPartitionKey - p.tableQueryOptions.NextRowKey = resp.XMSContinuationNextRowKey - return p.err == nil && resp.TableEntityQueryResponse.Value != nil && len(*resp.TableEntityQueryResponse.Value) > 0 -} - -func (p *structQueryResponsePager) PageResponse() StructQueryResponseResponse { - return *p.current -} - -func (p *structQueryResponsePager) Err() error { - return p.err -} - -// Pager for Table Queries -type TableQueryResponsePager interface { - // NextPage returns true if the pager advanced to the next page. - // Returns false if there are no more pages or an error occurred. - NextPage(context.Context) bool - - // Page returns the current TableQueryResponseResponse. - PageResponse() TableQueryResponseResponse - - // Err returns the last error encountered while paging. - Err() error -} - -type FromMapper interface { - FromMap(e *map[string]interface{}) interface{} -} - -type tableQueryResponsePager struct { - client *tableClient - current *TableQueryResponseResponse - tableQueryOptions *TableQueryOptions - queryOptions *QueryOptions - err error -} - -func (p *tableQueryResponsePager) NextPage(ctx context.Context) bool { - if p.err != nil || (p.current != nil && p.current.XMSContinuationNextTableName == nil) { - return false - } - var resp TableQueryResponseResponse - resp, p.err = p.client.Query(ctx, p.tableQueryOptions, p.queryOptions) - p.current = &resp - p.tableQueryOptions.NextTableName = resp.XMSContinuationNextTableName - return p.err == nil && resp.TableQueryResponse.Value != nil && len(*resp.TableQueryResponse.Value) > 0 -} - -func (p *tableQueryResponsePager) PageResponse() TableQueryResponseResponse { - return *p.current -} - -func (p *tableQueryResponsePager) Err() error { - return p.err -} - -func castAndRemoveAnnotationsSlice(entities *[]map[string]interface{}) { - for _, e := range *entities { - castAndRemoveAnnotations(&e) - } -} - -// TODO: The default behavior of json.Unmarshal is to deserialize all json numbers as Float64. -// This can be a problem for table entities which store float and int differently -func castAndRemoveAnnotations(entity *map[string]interface{}) error { - //value := (*entity)["value"].([]interface{})[0].(map[string]interface{}) - value := *entity - for k, v := range value { - - iSuffix := strings.Index(k, OdataType) - if iSuffix > 0 { - // Get the name of the property that this odataType key describes. - valueKey := k[0:iSuffix] - // get the string value of the value at the valueKey - valAsString := value[valueKey].(string) - - switch v { - case EdmBinary: - value[valueKey] = []byte(valAsString) - case EdmDateTime: - t, err := time.Parse(ISO8601, valAsString) - if err != nil { - return err - } - value[valueKey] = t - case EdmGuid: - value[valueKey] = uuid.Parse(valAsString) - case EdmInt64: - i, err := strconv.ParseInt(valAsString, 10, 64) - if err != nil { - return err - } - value[valueKey] = i - default: - return errors.New(fmt.Sprintf("unsupported annotation found: %s", k)) - } - // remove the annotation key - delete(value, k) - } - } - return nil -} - -func toOdataAnnotatedDictionary(entity *map[string]interface{}) error { - entMap := *entity - for k, v := range entMap { - t := reflect.TypeOf(v) - Switch: - switch t.Kind() { - case reflect.Slice, reflect.Array: - if GetTypeArray(v) != reflect.TypeOf(byte(0)) { - return errors.New("arrays and slices must be of type byte") - } - // check if this is a uuid - uuidVal, ok := v.(uuid.UUID) - if ok { - entMap[k] = uuidVal.String() - entMap[odataType(k)] = EdmGuid - } else { - entMap[odataType(k)] = EdmBinary - b := v.([]byte) - entMap[k] = base64.StdEncoding.EncodeToString(b) - } - case reflect.Struct: - switch tn := reflect.TypeOf(v).String(); tn { - case "time.Time": - entMap[odataType(k)] = EdmDateTime - time := v.(time.Time) - entMap[k] = time.UTC().Format(ISO8601) - continue - default: - return errors.New(fmt.Sprintf("Invalid struct for entity field '%s' of type '%s'", k, tn)) - } - case reflect.Float32, reflect.Float64: - entMap[odataType(k)] = EdmDouble - case reflect.Int64: - entMap[odataType(k)] = EdmInt64 - i64 := v.(int64) - entMap[k] = strconv.FormatInt(i64, 10) - case reflect.Ptr: - if v == nil { - // if the pointer is nil, ignore it. - continue - } - // follow the pointer to the type and re-run the switch - t = reflect.ValueOf(v).Elem().Type() - goto Switch - } - } - return nil -} - -func toMap(ent interface{}) (*map[string]interface{}, error) { - var s reflect.Value - if reflect.ValueOf(ent).Kind() == reflect.Ptr { - s = reflect.ValueOf(ent).Elem() - } else { - s = reflect.ValueOf(&ent).Elem().Elem() - } - typeOfT := s.Type() - nf := s.NumField() - entMap := make(map[string]interface{}, nf) - - for i := 0; i < nf; i++ { - v := s.Field(i) - Switch: - f := typeOfT.Field(i) - name := f.Name - if name == ETag || name == Timestamp { - // we do not need to serialize ETag or TimeStamp - continue - } - // add odata annotations for the types that require it. - switch k := v.Type().Kind(); k { - case reflect.Array, reflect.Slice: - if GetTypeArray(v.Interface()) != reflect.TypeOf(byte(0)) { - return nil, errors.New("arrays and slices must be of type byte") - } - // check if this is a uuid field as decorated by a tag - if _, ok := f.Tag.Lookup("uuid"); ok { - entMap[odataType(name)] = EdmGuid - u := v.Interface().([16]byte) - var uu uuid.UUID = u - entMap[name] = uu.String() - continue - } else { - entMap[odataType(name)] = EdmBinary - b := v.Interface().([]byte) - entMap[name] = base64.StdEncoding.EncodeToString(b) - continue - } - case reflect.Struct: - switch tn := v.Type().String(); tn { - case "time.Time": - entMap[odataType(name)] = EdmDateTime - time := v.Interface().(time.Time) - entMap[name] = time.UTC().Format(ISO8601) - continue - default: - return nil, errors.New(fmt.Sprintf("Invalid struct for entity field '%s' of type '%s'", typeOfT.Field(i).Name, tn)) - } - case reflect.Float32, reflect.Float64: - entMap[odataType(name)] = EdmDouble - case reflect.Int64: - entMap[odataType(name)] = EdmInt64 - i64 := v.Interface().(int64) - entMap[name] = strconv.FormatInt(i64, 10) - continue - case reflect.Ptr: - if v.IsNil() { - // if the pointer is nil, ignore it. - continue - } - // follow the pointer to the type and re-run the switch - v = v.Elem() - goto Switch - - // typeOfT.Field(i).Name, f.Type(), f.Interface()) - } - entMap[name] = v.Interface() - } - return &entMap, nil -} - -func fromMap(src interface{}, fmap *map[string]int, m *map[string]interface{}) (interface{}, error) { - tt := reflect.TypeOf(src) - srcVal := reflect.New(tt).Elem() - - for k, v := range *m { - // skip if this is an OData type descriptor - iSuffix := strings.Index(k, OdataType) - if iSuffix > 0 { - continue - } - // fetch the Field index by property name from the field map - fIndex := (*fmap)[k] - // Get the Value for the Field - val := srcVal.Field(fIndex) - Switch: - switch val.Kind() { - case reflect.String: - val.SetString(v.(string)) - case reflect.Float64: - val.SetFloat(v.(float64)) - case reflect.Int: - val.SetInt(int64(v.(float64))) - case reflect.Int64: - i64, err := strconv.ParseInt(v.(string), 10, 64) - if err != nil { - return nil, err - } - val.SetInt(i64) - case reflect.Struct: - switch tn := val.Type().String(); tn { - case "time.Time": - t, err := time.Parse(ISO8601, v.(string)) - if err != nil { - return nil, err - } - val.Set(reflect.ValueOf(t)) - } - case reflect.Ptr: - if val.IsNil() { - // populate the nil pointer with it's element type and re-run the type evaluation - val.Set(reflect.New(val.Type().Elem())) - val = val.Elem() - goto Switch - } - case reflect.Array, reflect.Map, reflect.Slice: - if GetTypeArray(val.Interface()) != reflect.TypeOf(byte(0)) { - return nil, errors.New("arrays and slices must be of type byte") - } - // // check if this is a uuid field as decorated by a tag - if _, ok := tt.Field(fIndex).Tag.Lookup("uuid"); ok { - u := uuid.Parse(v.(string)) - val.Set(reflect.ValueOf(u)) - } else { - b, err := base64.StdEncoding.DecodeString(v.(string)) - if err != nil { - return nil, err - } - val.SetBytes(b) - } - } - } - return srcVal.Interface(), nil -} - -// getTypeValueMap - builds a map of Field names to their Field index for the given interface{} -func getTypeValueMap(i interface{}) *map[string]int { - tt := reflect.TypeOf(complexEntity{}) - nf := tt.NumField() - fmap := make(map[string]int) - // build a map of field types - for i := 0; i < nf; i++ { - f := tt.Field(i) - fmap[f.Name] = i - if f.Name == ETag { - fmap[EtagOdata] = i - } - } - return &fmap -} - -func odataType(n string) string { - var b strings.Builder - b.Grow(len(n) + len(OdataType)) - b.WriteString(n) - b.WriteString(OdataType) - return b.String() -} - -func GetTypeArray(arr interface{}) reflect.Type { - return reflect.TypeOf(arr).Elem() -} diff --git a/sdk/tables/aztables/zc_table_pagers_test.go b/sdk/tables/aztables/zc_table_pagers_test.go deleted file mode 100644 index 44a3eb99fb47..000000000000 --- a/sdk/tables/aztables/zc_table_pagers_test.go +++ /dev/null @@ -1,244 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -package aztables - -import ( - "encoding/base64" - "encoding/json" - "fmt" - "io" - "io/ioutil" - "math" - "net/http" - "strconv" - "strings" - "testing" - "time" - - "github.com/Azure/azure-sdk-for-go/sdk/azcore" - "github.com/Azure/azure-sdk-for-go/sdk/internal/uuid" - "github.com/stretchr/testify/assert" -) - -type pagerTests struct{} - -func TestCastAndRemoveAnnotations(t *testing.T) { - assert := assert.New(t) - - r := &http.Response{Body: closerFromString(complexPayload)} - resp := azcore.Response{Response: r} - - var val map[string]interface{} - err := resp.UnmarshalAsJSON(&val) - assert.Nil(err) - err = castAndRemoveAnnotations(&val) - assert.Nil(err) - // assert all odata annotations are removed. - for k := range val { - assert.NotContains(k, OdataType) - } - - assert.IsType(time.Now(), val["SomeDateProperty"]) - assert.IsType([]byte{}, val["SomeBinaryProperty"]) - assert.IsType(float64(0), val["SomeDoubleProperty0"]) - // TODO: fix this - // assert.IsType(int(0), (*entity)["SomeIntProperty"]) -} - -func TestToOdataAnnotatedDictionary(t *testing.T) { - assert := assert.New(t) - - var val = createComplexEntityMap() - err := toOdataAnnotatedDictionary(&val) - assert.Nil(err) - // assert all odata annotations are removed. - for k := range odataHintProps { - _, ok := val[k] - assert.Truef(ok, fmt.Sprintf("map does not contain %s", k)) - iSuffix := strings.Index(k, OdataType) - if iSuffix > 0 { - // Get the name of the property that this odataType key describes. - valueKey := k[0:iSuffix] - if !strings.Contains(valueKey, "SomeDoubleProperty") { - assert.IsTypef("", val[valueKey], fmt.Sprintf("should be type string %s", valueKey)) - } - } - _, ok = val[odataType(k)] - assert.Truef(ok, fmt.Sprintf("map does not contain %s", odataType(k))) - } -} - -func BenchmarkUnMarshal_AsJson_CastAndRemove_Map(b *testing.B) { - assert := assert.New(b) - b.ReportAllocs() - bt := []byte(complexPayload) - for i := 0; i < b.N; i++ { - var val = make(map[string]interface{}) - json.Unmarshal(bt, &val) - castAndRemoveAnnotations(&val) - assert.Equal("somePartition", val["PartitionKey"]) - } -} - -func BenchmarkUnMarshal_FromMap_Entity(b *testing.B) { - assert := assert.New(b) - fmap := getTypeValueMap(complexEntity{}) - bt := []byte(complexPayload) - for i := 0; i < b.N; i++ { - var val = make(map[string]interface{}) - json.Unmarshal(bt, &val) - result, err := fromMap(complexEntity{}, fmap, &val) - assert.Nil(err) - ent := result.(complexEntity) - assert.Equal("somePartition", ent.PartitionKey) - } -} - -func BenchmarkMarshal_Entity_ToMap_ToOdataDict_Map(b *testing.B) { - ent := createComplexEntity() - for i := 0; i < b.N; i++ { - m, _ := toMap(ent) - toOdataAnnotatedDictionary(m) - json.Marshal(m) - } -} - -func BenchmarkMarshal_Map_ToOdataDict_Map(b *testing.B) { - ent := createComplexEntityMap() - for i := 0; i < b.N; i++ { - toOdataAnnotatedDictionary(&ent) - json.Marshal(ent) - } -} - -func TestToMap(t *testing.T) { - assert := assert.New(t) - - ent := createComplexEntity() - - entMap, err := toMap(ent) - assert.Nil(err) - - // Validate that we have all the @odata.type properties for types []byte, int64, float64, time.Time, and uuid - for k, v := range odataHintProps { - vv, ok := (*entMap)[odataType(k)] - assert.Truef(ok, "Should have found map key of name '%s'", odataType(k)) - assert.Equal(v, vv) - } - - // validate all the types were properly casted / converted - assert.Equal(ent.PartitionKey, (*entMap)["PartitionKey"]) - assert.Equal(ent.RowKey, (*entMap)["RowKey"]) - assert.Equal(base64.StdEncoding.EncodeToString(ent.SomeBinaryProperty), string((*entMap)["SomeBinaryProperty"].(string))) - ts, _ := time.Parse(ISO8601, (*entMap)["SomeDateProperty"].(string)) - assert.Equal(ent.SomeDateProperty.UTC().Format(ISO8601), ts.Format(ISO8601)) - assert.Equal(ent.SomeDoubleProperty0, (*entMap)["SomeDoubleProperty0"]) - assert.Equal(ent.SomeDoubleProperty1, (*entMap)["SomeDoubleProperty1"]) - var u uuid.UUID = ent.SomeGuidProperty - assert.Equal(u.String(), (*entMap)["SomeGuidProperty"].(string)) - assert.Equal(strconv.FormatInt(ent.SomeInt64Property, 10), (*entMap)["SomeInt64Property"].(string)) - assert.Equal(ent.SomeIntProperty, (*entMap)["SomeIntProperty"]) - assert.Equal(ent.SomeStringProperty, (*entMap)["SomeStringProperty"]) - assert.Equal(*ent.SomePtrStringProperty, (*entMap)["SomePtrStringProperty"]) -} - -func TestEntitySerialization(t *testing.T) { - assert := assert.New(t) - - ent := createComplexEntity() - - b, err := json.Marshal(ent) - assert.Nil(err) - assert.NotEmpty(b) - s := string(b) - //assert.FailNow(s) - assert.NotEmpty(s) -} - -func TestDeserializeFromMap(t *testing.T) { - assert := assert.New(t) - - expected := createComplexEntity() - bt := []byte(complexPayload) - var val = make(map[string]interface{}) - json.Unmarshal(bt, &val) - result, err := fromMap(complexEntity{}, getTypeValueMap(complexEntity{}), &val) - assert.Nil(err) - ent := result.(complexEntity) - assert.EqualValues(expected, ent) -} - -func createComplexEntity() complexEntity { - sp := "some pointer to string" - t, _ := time.Parse(ISO8601, "2021-03-23T18:29:15.9686039Z") - t2, _ := time.Parse(ISO8601, "2020-01-01T01:02:00Z") - b, _ := base64.StdEncoding.DecodeString("AQIDBAU=") - var e = complexEntity{ - PartitionKey: "somePartition", - ETag: "W/\"datetime'2021-04-05T05%3A02%3A40.7371784Z'\"", - RowKey: "01", - Timestamp: t, - SomeBinaryProperty: b, - SomeDateProperty: t2, - SomeDoubleProperty0: float64(1.0), - SomeDoubleProperty1: float64(1.5), - SomeGuidProperty: uuid.Parse("0d391d16-97f1-4b9a-be68-4cc871f90001"), - SomeInt64Property: int64(math.MaxInt64), - SomeIntProperty: 42, - SomeStringProperty: "This is table entity number 01", - SomePtrStringProperty: &sp} - return e -} - -func createComplexEntityMap() map[string]interface{} { - sp := "some pointer to string" - t, _ := time.Parse(ISO8601, "2021-03-23T18:29:15.9686039Z") - t2, _ := time.Parse(ISO8601, "2020-01-01T01:02:00Z") - b, _ := base64.StdEncoding.DecodeString("AQIDBAU=") - var e = map[string]interface{}{ - "PartitionKey": "somePartition", - "ETag": "W/\"datetime'2021-04-05T05%3A02%3A40.7371784Z'\"", - "RowKey": "01", - "Timestamp": t, - "SomeBinaryProperty": b, - "SomeDateProperty": t2, - "SomeDoubleProperty0": float64(1.0), - "SomeDoubleProperty1": float64(1.5), - "SomeGuidProperty": uuid.Parse("0d391d16-97f1-4b9a-be68-4cc871f90001"), - "SomeInt64Property": int64(math.MaxInt64), - "SomeIntProperty": 42, - "SomeStringProperty": "This is table entity number 01", - "SomePtrStringProperty": &sp} - return e -} - -func closerFromString(content string) io.ReadCloser { - return ioutil.NopCloser(strings.NewReader(content)) -} - -var odataHintProps = map[string]string{ - "SomeBinaryProperty": EdmBinary, - "SomeDateProperty": EdmDateTime, - "SomeDoubleProperty0": EdmDouble, - "SomeDoubleProperty1": EdmDouble, - "SomeGuidProperty": EdmGuid, - "SomeInt64Property": EdmInt64} - -var complexPayload = "{\"odata.etag\": \"W/\\\"datetime'2021-04-05T05%3A02%3A40.7371784Z'\\\"\"," + - "\"PartitionKey\": \"somePartition\"," + - "\"RowKey\": \"01\"," + - "\"Timestamp\": \"2021-03-23T18:29:15.9686039Z\"," + - "\"SomeBinaryProperty@odata.type\": \"Edm.Binary\"," + - "\"SomeBinaryProperty\": \"AQIDBAU=\"," + - "\"SomeDateProperty@odata.type\": \"Edm.DateTime\"," + - "\"SomeDateProperty\": \"2020-01-01T01:02:00Z\"," + - "\"SomeDoubleProperty0\": 1.0," + - "\"SomeDoubleProperty1\": 1.5," + - "\"SomeGuidProperty@odata.type\": \"Edm.Guid\"," + - "\"SomeGuidProperty\": \"0d391d16-97f1-4b9a-be68-4cc871f90001\"," + - "\"SomeInt64Property@odata.type\": \"Edm.Int64\"," + - "\"SomeInt64Property\": \"" + strconv.FormatInt(math.MaxInt64, 10) + "\"," + - "\"SomeIntProperty\": 42," + - "\"SomeStringProperty\": \"This is table entity number 01\"," + - "\"SomePtrStringProperty\": \"some pointer to string\" }" diff --git a/sdk/tables/aztables/zt_tableRecordedTests.go b/sdk/tables/aztables/zt_tableRecordedTests.go deleted file mode 100644 index 7c42ec9545ab..000000000000 --- a/sdk/tables/aztables/zt_tableRecordedTests.go +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -package aztables - -import ( - "context" - "fmt" - "math" - "testing" - "time" - - "github.com/Azure/azure-sdk-for-go/sdk/azcore" - "github.com/Azure/azure-sdk-for-go/sdk/internal/testframework" - "github.com/stretchr/testify/assert" -) - -type tablesRecordedTests struct{} - -type testContext struct { - recording *testframework.Recording - client *TableServiceClient - context *testframework.TestContext -} - -const ( - storageAccountNameEnvVar = "TABLES_STORAGE_ACCOUNT_NAME" - cosmosAccountNameEnnVar = "TABLES_COSMOS_ACCOUNT_NAME" - storageEndpointSuffixEnvVar = "STORAGE_ENDPOINT_SUFFIX" - cosmosEndpointSuffixEnvVar = "COSMOS_TABLES_ENDPOINT_SUFFIX" - storageAccountKeyEnvVar = "TABLES_PRIMARY_STORAGE_ACCOUNT_KEY" - cosmosAccountKeyEnvVar = "TABLES_PRIMARY_COSMOS_ACCOUNT_KEY" - tableNamePrefix = "gotable" - DefaultStorageSuffix = "core.windows.net" - DefaultCosmosSuffix = "cosmos.azure.com" -) - -type EndpointType string - -const ( - StorageEndpoint EndpointType = "storage" - CosmosEndpoint EndpointType = "cosmos" -) - -var ctx = context.Background() -var clientsMap map[string]*testContext = make(map[string]*testContext) - -func storageURI(accountName string, endpointSuffix string) string { - return "https://" + accountName + ".table." + endpointSuffix -} - -func cosmosURI(accountName string, endpointSuffix string) string { - return "https://" + accountName + ".table." + endpointSuffix -} - -// create the test specific TableClient and wire it up to recordings -func recordedTestSetup(t *testing.T, testName string, endpointType EndpointType, mode testframework.RecordMode) { - var accountName string - var suffix string - var cred *SharedKeyCredential - var secret string - var uri string - assert := assert.New(t) - - // init the test framework - context := testframework.NewTestContext(func(msg string) { assert.FailNow(msg) }, func(msg string) { t.Log(msg) }, func() string { return testName }) - recording, err := testframework.NewRecording(context, mode) - assert.Nil(err) - - if endpointType == StorageEndpoint { - accountName, err = recording.GetRecordedVariable(storageAccountNameEnvVar, testframework.Default) - suffix = recording.GetOptionalRecordedVariable(storageEndpointSuffixEnvVar, DefaultStorageSuffix, testframework.Default) - secret, err = recording.GetRecordedVariable(storageAccountKeyEnvVar, testframework.Secret_Base64String) - cred, _ = NewSharedKeyCredential(accountName, secret) - uri = storageURI(accountName, suffix) - } else { - accountName, err = recording.GetRecordedVariable(cosmosAccountNameEnnVar, testframework.Default) - suffix = recording.GetOptionalRecordedVariable(cosmosEndpointSuffixEnvVar, DefaultCosmosSuffix, testframework.Default) - secret, err = recording.GetRecordedVariable(cosmosAccountKeyEnvVar, testframework.Secret_Base64String) - cred, _ = NewSharedKeyCredential(accountName, secret) - uri = cosmosURI(accountName, suffix) - } - - client, err := NewTableServiceClient(uri, cred, &TableClientOptions{HTTPClient: recording, Retry: azcore.RetryOptions{MaxRetries: -1}}) - assert.Nil(err) - clientsMap[testName] = &testContext{client: client, recording: recording, context: &context} -} - -func recordedTestTeardown(key string) { - context, ok := clientsMap[key] - if ok && !(*context.context).IsFailed() { - context.recording.Stop() - } -} - -// cleans up the specified tables. If tables is nil, all tables will be deleted -func cleanupTables(context *testContext, tables *[]string) { - c := context.client - if tables == nil { - pager := c.QueryTables(QueryOptions{}) - for pager.NextPage(ctx) { - for _, t := range *(pager.PageResponse().TableQueryResponse.Value) { - c.Delete(ctx, *t.TableName) - } - } - } else { - for _, t := range *tables { - c.Delete(ctx, t) - } - } -} - -func getTestContext(key string) *testContext { - return clientsMap[key] -} - -func getTableName(context *testContext, prefix ...string) (string, error) { - if len(prefix) == 0 { - return context.recording.GenerateAlphaNumericID(tableNamePrefix, 20, true) - } else { - return context.recording.GenerateAlphaNumericID(prefix[0], 20, true) - } -} - -func createSimpleEntities(count int, pk string) *[]map[string]interface{} { - result := make([]map[string]interface{}, count) - - for i := 1; i <= count; i++ { - var e = map[string]interface{}{ - PartitionKey: pk, - RowKey: fmt.Sprint(i), - "StringProp": fmt.Sprintf("some string %d", i), - "IntProp": i, - "BoolProp": true, - } - result[i-1] = e - } - return &result -} - -func createComplexEntities(context *testContext, count int, pk string) *[]complexEntity { - result := make([]complexEntity, count) - - sp := "some pointer to string" - for i := 1; i <= count; i++ { - var e = complexEntity{ - PartitionKey: "partition", - ETag: "*", - RowKey: "row", - Timestamp: context.recording.Now(), - SomeBinaryProperty: []byte("some bytes"), - SomeDateProperty: context.recording.Now(), - SomeDoubleProperty0: float64(1), - SomeDoubleProperty1: float64(1.2345), - SomeGuidProperty: context.recording.UUID(), - SomeInt64Property: math.MaxInt64, - SomeIntProperty: 42, - SomeStringProperty: "some string", - SomePtrStringProperty: &sp} - result[i-1] = e - } - return &result -} - -type complexEntity struct { - ETag string - PartitionKey string - RowKey string - Timestamp time.Time - SomeBinaryProperty []byte - SomeDateProperty time.Time - SomeDoubleProperty0 float64 - SomeDoubleProperty1 float64 - SomeGuidProperty [16]byte `uuid:""` - SomeInt64Property int64 - SomeIntProperty int - SomeStringProperty string - SomePtrStringProperty *string -} diff --git a/sdk/tables/aztables/zt_test.go b/sdk/tables/aztables/zt_test.go new file mode 100644 index 000000000000..c9e649bca203 --- /dev/null +++ b/sdk/tables/aztables/zt_test.go @@ -0,0 +1,123 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package aztables + +import ( + "context" + "errors" + "fmt" + "os" + "testing" + "time" + + chk "gopkg.in/check.v1" +) + +// For testing docs, see: https://labix.org/gocheck +// To test a specific test: go test -check.f MyTestSuite + +// Hookup to the testing framework +func Test(t *testing.T) { chk.TestingT(t) } + +type aztestsSuite struct{} + +var _ = chk.Suite(&aztestsSuite{}) + +const ( + storageAccountNameEnvVar = "TABLES_STORAGE_ACCOUNT_NAME" + cosmosAccountNameEnnVar = "TABLES_COSMOS_ACCOUNT_NAME" + accountKeyEnvVar = "TABLES_PRIMARY_STORAGE_ACCOUNT_KEY" + storageEndpointSuffixEnvVar = "STORAGE_ENDPOINT_SUFFIX" + cosmosEndpointSuffixEnvVar = "COSMOS_TABLES_ENDPOINT_SUFFIX" + storageAccountKeyEnvVar = "TABLES_PRIMARY_STORAGE_ACCOUNT_KEY" + cosmosAccountKeyEnvVar = "TABLES_PRIMARY_COSMOS_ACCOUNT_KEY" + tableNamePrefix = "gotable" + DefaultStorageSuffix = "core.windows.net" + DefaultCosmosSuffix = "cosmos.azure.com" +) + +type EndpointType string + +const ( + StorageEndpoint EndpointType = "storage" + CosmosEndpoint EndpointType = "cosmos" +) + +var ctx = context.Background() + +func getRequiredEnv(name string) string { + env, ok := os.LookupEnv(name) + if ok { + return env + } else { + panic("Required environment variable not set: " + name) + } +} + +func storageURI() string { + return "https://" + storageAccountName() + ".table." + storageEndpointSuffix() +} + +func cosmosURI() string { + return "https://" + cosmosAccountName() + ".table" + cosmosAccountName() +} + +func storageAccountName() string { + return getRequiredEnv(storageAccountNameEnvVar) +} + +func cosmosAccountName() string { + return getRequiredEnv(cosmosAccountNameEnnVar) +} + +func cosmosAccountKey() string { + return getRequiredEnv(cosmosAccountKeyEnvVar) +} + +func storageAccountKey() string { + return getRequiredEnv(storageAccountKeyEnvVar) +} + +func storageEndpointSuffix() string { + suffix, ok := os.LookupEnv(storageEndpointSuffixEnvVar) + if ok { + return suffix + } else { + return DefaultStorageSuffix + } +} + +func cosmosEndpointSuffix() string { + suffix, ok := os.LookupEnv(cosmosEndpointSuffix()) + if ok { + return suffix + } else { + return DefaultCosmosSuffix + } +} + +func createTableClient(endpointType EndpointType) (*TableClient, error) { + if endpointType == StorageEndpoint { + storageCred, _ := NewSharedKeyCredential(storageAccountName(), storageAccountKey()) + return NewTableClient(storageURI(), storageCred, nil) + } else { + cosmosCred, _ := NewSharedKeyCredential(cosmosAccountName(), cosmosAccountKey()) + return NewTableClient(cosmosURI(), cosmosCred, nil) + } +} + +func getGenericCredential(accountType string) (*SharedKeyCredential, error) { + + accountName, accountKey := getRequiredEnv(storageAccountNameEnvVar), getRequiredEnv(accountKeyEnvVar) + if accountName == "" || accountKey == "" { + return nil, errors.New(storageAccountNameEnvVar + " and/or " + accountKeyEnvVar + " environment variables not specified.") + } + return NewSharedKeyCredential(accountName, accountKey) +} + +func generateName() string { + currentTime := time.Now() + name := fmt.Sprintf("%s%d%d%d", tableNamePrefix, currentTime.Minute(), currentTime.Second(), currentTime.Nanosecond()) + return name +} diff --git a/sdk/tables/aztables/zz_generated_connection.go b/sdk/tables/aztables/zz_generated_connection.go index 325fa053b1bd..990122c2b6e3 100644 --- a/sdk/tables/aztables/zz_generated_connection.go +++ b/sdk/tables/aztables/zz_generated_connection.go @@ -14,7 +14,6 @@ import ( const scope = "foo" const telemetryInfo = "azsdk-go-tables/" - // connectionOptions contains configuration settings for the connection's pipeline. // All zero-value fields will be initialized with their default values. type connectionOptions struct { @@ -68,6 +67,7 @@ func (c *connection) Endpoint() string { } // Pipeline returns the connection's pipeline. -func (c *connection) Pipeline() azcore.Pipeline { +func (c *connection) Pipeline() (azcore.Pipeline) { return c.p } + From 3632e779a77e29dde9d822493f3383a6df3556f9 Mon Sep 17 00:00:00 2001 From: Christopher Scott Date: Wed, 21 Apr 2021 09:29:06 -0500 Subject: [PATCH 17/18] gofmt --- sdk/tables/aztables/zc_client_options.go | 6 +++--- sdk/tables/aztables/zz_generated_connection.go | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sdk/tables/aztables/zc_client_options.go b/sdk/tables/aztables/zc_client_options.go index cf24278fd2d2..f0a7200fd141 100644 --- a/sdk/tables/aztables/zc_client_options.go +++ b/sdk/tables/aztables/zc_client_options.go @@ -23,7 +23,7 @@ func (o *TableClientOptions) getConnectionOptions() *connectionOptions { return &connectionOptions{ HTTPClient: o.HTTPClient, - Retry: o.Retry, - Telemetry: o.Telemetry, + Retry: o.Retry, + Telemetry: o.Telemetry, } -} \ No newline at end of file +} diff --git a/sdk/tables/aztables/zz_generated_connection.go b/sdk/tables/aztables/zz_generated_connection.go index 990122c2b6e3..325fa053b1bd 100644 --- a/sdk/tables/aztables/zz_generated_connection.go +++ b/sdk/tables/aztables/zz_generated_connection.go @@ -14,6 +14,7 @@ import ( const scope = "foo" const telemetryInfo = "azsdk-go-tables/" + // connectionOptions contains configuration settings for the connection's pipeline. // All zero-value fields will be initialized with their default values. type connectionOptions struct { @@ -67,7 +68,6 @@ func (c *connection) Endpoint() string { } // Pipeline returns the connection's pipeline. -func (c *connection) Pipeline() (azcore.Pipeline) { +func (c *connection) Pipeline() azcore.Pipeline { return c.p } - From 037d5cc87bd6dbaf2e05323f17a1fb3f5c15e8e6 Mon Sep 17 00:00:00 2001 From: Christopher Scott Date: Wed, 21 Apr 2021 10:00:34 -0500 Subject: [PATCH 18/18] test --- sdk/tables/aztables/tableClient.go | 1 + sdk/tables/aztables/tableClient_test.go | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/sdk/tables/aztables/tableClient.go b/sdk/tables/aztables/tableClient.go index edc74ece6075..d24ae0a14931 100644 --- a/sdk/tables/aztables/tableClient.go +++ b/sdk/tables/aztables/tableClient.go @@ -5,6 +5,7 @@ package aztables import ( "context" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" ) diff --git a/sdk/tables/aztables/tableClient_test.go b/sdk/tables/aztables/tableClient_test.go index 0b76e48fd15d..45b97edc2d47 100644 --- a/sdk/tables/aztables/tableClient_test.go +++ b/sdk/tables/aztables/tableClient_test.go @@ -4,9 +4,15 @@ package aztables import ( - chk "gopkg.in/check.v1" // go get gopkg.in/check.v1 + "testing" ) -func (s *aztestsSuite) TestContainerCreateAccessContainer(c *chk.C) { +func TestContainerCreateAccessContainer(t *testing.T) { // TODO + cred, err := NewSharedKeyCredential("foo", "Kg==") + if err != nil { + t.Fatal(err) + } + + NewTableClient("https://foo", cred, &TableClientOptions{}) }